@@ -441,30 +441,27 @@ CompilerProto.bindDirective = function (directive) {
441441 */
442442CompilerProto . createBinding = function ( key , isExp , isFn ) {
443443
444+ log ( ' created binding: ' + key )
445+
444446 var compiler = this ,
445447 bindings = compiler . bindings ,
448+ computed = compiler . options . computed ,
446449 binding = new Binding ( compiler , key , isExp , isFn )
447450
448451 if ( isExp ) {
449- // a complex expression binding
450- // we need to generate an anonymous computed property for it
451- var getter = ExpParser . parse ( key , compiler )
452- if ( getter ) {
453- log ( ' created expression binding: ' + key )
454- binding . value = isFn
455- ? getter
456- : { $get : getter }
457- compiler . markComputed ( binding )
458- compiler . exps . push ( binding )
459- }
452+ // expression bindings are anonymous
453+ compiler . defineExp ( key , binding )
460454 } else {
461- log ( ' created binding: ' + key )
462455 bindings [ key ] = binding
463- // make sure the key exists in the object so it can be observed
464- // by the Observer!
465456 if ( binding . root ) {
466457 // this is a root level binding. we need to define getter/setters for it.
467- compiler . define ( key , binding )
458+ if ( computed && computed [ key ] ) {
459+ // computed property
460+ compiler . defineComputed ( key , binding , computed [ key ] )
461+ } else {
462+ // normal property
463+ compiler . defineProp ( key , binding )
464+ }
468465 } else {
469466 // ensure path in data so it can be observed
470467 Observer . ensurePath ( compiler . data , key )
@@ -480,70 +477,82 @@ CompilerProto.createBinding = function (key, isExp, isFn) {
480477}
481478
482479/**
483- * Defines the getter/setter for a root-level binding on the VM
480+ * Define the getter/setter for a root-level property on the VM
484481 * and observe the initial value
485482 */
486- CompilerProto . define = function ( key , binding ) {
487-
488- log ( ' defined root binding: ' + key )
489-
483+ CompilerProto . defineProp = function ( key , binding ) {
484+
490485 var compiler = this ,
491486 data = compiler . data ,
492- vm = compiler . vm ,
493- comps = compiler . options . computed ,
494- ob = data . __observer__ ,
495- value
496-
497- if ( comps && comps [ key ] ) {
498- // computed property
499- value = binding . value = comps [ key ]
500- compiler . markComputed ( binding )
501- } else {
502- if ( ! ( key in data ) ) {
503- data [ key ] = undefined
504- }
505- // if the data object is already observed, but the key
506- // is not observed, we need to add it to the observed keys.
507- if ( ob && ! ( key in ob . values ) ) {
508- Observer . convert ( data , key )
509- }
510- value = binding . value = data [ key ]
487+ ob = data . __observer__
488+
489+ // make sure the key is present in data
490+ // so it can be observed
491+ if ( ! ( key in data ) ) {
492+ data [ key ] = undefined
511493 }
512494
513- Object . defineProperty ( vm , key , {
514- get : binding . isComputed
515- ? function ( ) {
516- return binding . value . $get ( )
517- }
518- : function ( ) {
519- return compiler . data [ key ]
520- } ,
521- set : binding . isComputed
522- ? function ( val ) {
523- if ( binding . value . $set ) {
524- binding . value . $set ( val )
525- }
526- }
527- : function ( val ) {
528- compiler . data [ key ] = val
529- }
495+ // if the data object is already observed, but the key
496+ // is not observed, we need to add it to the observed keys.
497+ if ( ob && ! ( key in ob . values ) ) {
498+ Observer . convert ( data , key )
499+ }
500+
501+ binding . value = data [ key ]
502+
503+ Object . defineProperty ( compiler . vm , key , {
504+ get : function ( ) {
505+ return compiler . data [ key ]
506+ } ,
507+ set : function ( val ) {
508+ compiler . data [ key ] = val
509+ }
530510 } )
531511}
532512
513+ /**
514+ * Define an expression binding, which is essentially
515+ * an anonymous computed property
516+ */
517+ CompilerProto . defineExp = function ( key , binding ) {
518+ var getter = ExpParser . parse ( key , this )
519+ if ( getter ) {
520+ var value = binding . isFn
521+ ? getter
522+ : { $get : getter }
523+ this . markComputed ( binding , value )
524+ this . exps . push ( binding )
525+ }
526+ }
527+
528+ /**
529+ * Define a computed property on the VM
530+ */
531+ CompilerProto . defineComputed = function ( key , binding , value ) {
532+ this . markComputed ( binding , value )
533+ var def = {
534+ get : binding . value . $get
535+ }
536+ if ( binding . value . $set ) {
537+ def . set = binding . value . $set
538+ }
539+ Object . defineProperty ( this . vm , key , def )
540+ }
541+
533542/**
534543 * Process a computed property binding
544+ * so its getter/setter are bound to proper context
535545 */
536- CompilerProto . markComputed = function ( binding ) {
537- var value = binding . value ,
538- vm = this . vm
546+ CompilerProto . markComputed = function ( binding , value ) {
547+ binding . value = value
539548 binding . isComputed = true
540549 // bind the accessors to the vm
541550 if ( ! binding . isFn ) {
542551 binding . value = {
543- $get : utils . bind ( value . $get , vm )
552+ $get : utils . bind ( value . $get , this . vm )
544553 }
545554 if ( value . $set ) {
546- binding . value . $set = utils . bind ( value . $set , vm )
555+ binding . value . $set = utils . bind ( value . $set , this . vm )
547556 }
548557 }
549558 // keep track for dep parsing later
0 commit comments