11/*
2- VueJS v0.8.1
2+ Vue.js v0.8.2
33 (c) 2014 Evan You
44 License: MIT
55*/
@@ -843,6 +843,7 @@ function Compiler (vm, options) {
843843 compiler . vm = vm
844844 compiler . bindings = makeHash ( )
845845 compiler . dirs = [ ]
846+ compiler . deferred = [ ]
846847 compiler . exps = [ ]
847848 compiler . computed = [ ]
848849 compiler . childCompilers = [ ]
@@ -915,11 +916,14 @@ function Compiler (vm, options) {
915916 // and bind the parsed directives
916917 compiler . compile ( el , true )
917918
918- // extract dependencies for computed properties
919- if ( compiler . computed . length ) {
920- DepsParser . parse ( compiler . computed )
919+ // bind deferred directives (child components)
920+ for ( var i = 0 , l = compiler . deferred . length ; i < l ; i ++ ) {
921+ compiler . bindDirective ( compiler . deferred [ i ] )
921922 }
922923
924+ // extract dependencies for computed properties
925+ compiler . parseDeps ( )
926+
923927 // done!
924928 compiler . init = false
925929
@@ -1045,7 +1049,10 @@ CompilerProto.compile = function (node, root) {
10451049 directive = Directive . parse ( 'repeat' , repeatExp , compiler , node )
10461050 if ( directive ) {
10471051 directive . Ctor = componentCtor
1048- compiler . bindDirective ( directive )
1052+ // defer child component compilation
1053+ // so by the time they are compiled, the parent
1054+ // would have collected all bindings
1055+ compiler . deferred . push ( directive )
10491056 }
10501057
10511058 // v-with has 2nd highest priority
@@ -1054,7 +1061,7 @@ CompilerProto.compile = function (node, root) {
10541061 directive = Directive . parse ( 'with' , withKey || '' , compiler , node )
10551062 if ( directive ) {
10561063 directive . Ctor = componentCtor
1057- compiler . bindDirective ( directive )
1064+ compiler . deferred . push ( directive )
10581065 }
10591066
10601067 } else {
@@ -1389,6 +1396,14 @@ CompilerProto.hasKey = function (key) {
13891396 hasOwn . call ( this . vm , baseKey )
13901397}
13911398
1399+ /**
1400+ * Collect dependencies for computed properties
1401+ */
1402+ CompilerProto . parseDeps = function ( ) {
1403+ if ( ! this . computed . length ) return
1404+ DepsParser . parse ( this . computed )
1405+ }
1406+
13921407/**
13931408 * Unbind and remove element
13941409 */
@@ -2476,6 +2491,7 @@ function catchDeps (binding) {
24762491 if ( binding . isFn ) return
24772492 utils . log ( '\n- ' + binding . key )
24782493 var got = utils . hash ( )
2494+ binding . deps = [ ]
24792495 catcher . on ( 'get' , function ( dep ) {
24802496 var has = got [ dep . key ]
24812497 if ( has && has . compiler === dep . compiler ) return
@@ -2501,7 +2517,8 @@ module.exports = {
25012517 parse : function ( bindings ) {
25022518 utils . log ( '\nparsing dependencies...' )
25032519 Observer . shouldGet = true
2504- bindings . forEach ( catchDeps )
2520+ var i = bindings . length
2521+ while ( i -- ) { catchDeps ( bindings [ i ] ) }
25052522 Observer . shouldGet = false
25062523 utils . log ( '\ndone.' )
25072524 }
@@ -3009,38 +3026,59 @@ module.exports = {
30093026 if ( method !== 'push' && method !== 'pop' ) {
30103027 self . updateIndexes ( )
30113028 }
3029+ if ( method === 'push' || method === 'unshift' || method === 'splice' ) {
3030+ self . changed ( )
3031+ }
30123032 }
30133033
30143034 } ,
30153035
3016- update : function ( collection ) {
3036+ update : function ( collection , init ) {
30173037
3018- this . unbind ( true )
3038+ var self = this
3039+ self . unbind ( true )
30193040 // attach an object to container to hold handlers
3020- this . container . vue_dHandlers = utils . hash ( )
3041+ self . container . vue_dHandlers = utils . hash ( )
30213042 // if initiating with an empty collection, we need to
30223043 // force a compile so that we get all the bindings for
30233044 // dependency extraction.
3024- if ( ! this . initiated && ( ! collection || ! collection . length ) ) {
3025- this . buildItem ( )
3026- this . initiated = true
3045+ if ( ! self . initiated && ( ! collection || ! collection . length ) ) {
3046+ self . buildItem ( )
3047+ self . initiated = true
30273048 }
3028- collection = this . collection = collection || [ ]
3029- this . vms = [ ]
3049+ collection = self . collection = collection || [ ]
3050+ self . vms = [ ]
30303051
30313052 // listen for collection mutation events
30323053 // the collection has been augmented during Binding.set()
30333054 if ( ! collection . __observer__ ) Observer . watchArray ( collection , null , new Emitter ( ) )
3034- collection . __observer__ . on ( 'mutate' , this . mutationListener )
3055+ collection . __observer__ . on ( 'mutate' , self . mutationListener )
30353056
30363057 // create child-vms and append to DOM
30373058 if ( collection . length ) {
30383059 for ( var i = 0 , l = collection . length ; i < l ; i ++ ) {
3039- this . buildItem ( collection [ i ] , i )
3060+ self . buildItem ( collection [ i ] , i )
30403061 }
3062+ if ( ! init ) self . changed ( )
30413063 }
30423064 } ,
30433065
3066+ /**
3067+ * Notify parent compiler that new items
3068+ * have been added to the collection, it needs
3069+ * to re-calculate computed property dependencies.
3070+ * Batched to ensure it's called only once every event loop.
3071+ */
3072+ changed : function ( ) {
3073+ var self = this
3074+ if ( self . queued ) return
3075+ self . queued = true
3076+ setTimeout ( function ( ) {
3077+ self . compiler . parseDeps ( )
3078+ self . queued = false
3079+ } , 0 )
3080+ } ,
3081+
30443082 /**
30453083 * Create a new child VM from a data object
30463084 * passing along compiler options indicating this
0 commit comments