1
1
/*
2
- VueJS v0.8.1
2
+ Vue.js v0.8.2
3
3
(c) 2014 Evan You
4
4
License: MIT
5
5
*/
@@ -843,6 +843,7 @@ function Compiler (vm, options) {
843
843
compiler . vm = vm
844
844
compiler . bindings = makeHash ( )
845
845
compiler . dirs = [ ]
846
+ compiler . deferred = [ ]
846
847
compiler . exps = [ ]
847
848
compiler . computed = [ ]
848
849
compiler . childCompilers = [ ]
@@ -915,11 +916,14 @@ function Compiler (vm, options) {
915
916
// and bind the parsed directives
916
917
compiler . compile ( el , true )
917
918
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 ] )
921
922
}
922
923
924
+ // extract dependencies for computed properties
925
+ compiler . parseDeps ( )
926
+
923
927
// done!
924
928
compiler . init = false
925
929
@@ -1045,7 +1049,10 @@ CompilerProto.compile = function (node, root) {
1045
1049
directive = Directive . parse ( 'repeat' , repeatExp , compiler , node )
1046
1050
if ( directive ) {
1047
1051
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 )
1049
1056
}
1050
1057
1051
1058
// v-with has 2nd highest priority
@@ -1054,7 +1061,7 @@ CompilerProto.compile = function (node, root) {
1054
1061
directive = Directive . parse ( 'with' , withKey || '' , compiler , node )
1055
1062
if ( directive ) {
1056
1063
directive . Ctor = componentCtor
1057
- compiler . bindDirective ( directive )
1064
+ compiler . deferred . push ( directive )
1058
1065
}
1059
1066
1060
1067
} else {
@@ -1389,6 +1396,14 @@ CompilerProto.hasKey = function (key) {
1389
1396
hasOwn . call ( this . vm , baseKey )
1390
1397
}
1391
1398
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
+
1392
1407
/**
1393
1408
* Unbind and remove element
1394
1409
*/
@@ -2476,6 +2491,7 @@ function catchDeps (binding) {
2476
2491
if ( binding . isFn ) return
2477
2492
utils . log ( '\n- ' + binding . key )
2478
2493
var got = utils . hash ( )
2494
+ binding . deps = [ ]
2479
2495
catcher . on ( 'get' , function ( dep ) {
2480
2496
var has = got [ dep . key ]
2481
2497
if ( has && has . compiler === dep . compiler ) return
@@ -2501,7 +2517,8 @@ module.exports = {
2501
2517
parse : function ( bindings ) {
2502
2518
utils . log ( '\nparsing dependencies...' )
2503
2519
Observer . shouldGet = true
2504
- bindings . forEach ( catchDeps )
2520
+ var i = bindings . length
2521
+ while ( i -- ) { catchDeps ( bindings [ i ] ) }
2505
2522
Observer . shouldGet = false
2506
2523
utils . log ( '\ndone.' )
2507
2524
}
@@ -3009,38 +3026,59 @@ module.exports = {
3009
3026
if ( method !== 'push' && method !== 'pop' ) {
3010
3027
self . updateIndexes ( )
3011
3028
}
3029
+ if ( method === 'push' || method === 'unshift' || method === 'splice' ) {
3030
+ self . changed ( )
3031
+ }
3012
3032
}
3013
3033
3014
3034
} ,
3015
3035
3016
- update : function ( collection ) {
3036
+ update : function ( collection , init ) {
3017
3037
3018
- this . unbind ( true )
3038
+ var self = this
3039
+ self . unbind ( true )
3019
3040
// attach an object to container to hold handlers
3020
- this . container . vue_dHandlers = utils . hash ( )
3041
+ self . container . vue_dHandlers = utils . hash ( )
3021
3042
// if initiating with an empty collection, we need to
3022
3043
// force a compile so that we get all the bindings for
3023
3044
// 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
3027
3048
}
3028
- collection = this . collection = collection || [ ]
3029
- this . vms = [ ]
3049
+ collection = self . collection = collection || [ ]
3050
+ self . vms = [ ]
3030
3051
3031
3052
// listen for collection mutation events
3032
3053
// the collection has been augmented during Binding.set()
3033
3054
if ( ! collection . __observer__ ) Observer . watchArray ( collection , null , new Emitter ( ) )
3034
- collection . __observer__ . on ( 'mutate' , this . mutationListener )
3055
+ collection . __observer__ . on ( 'mutate' , self . mutationListener )
3035
3056
3036
3057
// create child-vms and append to DOM
3037
3058
if ( collection . length ) {
3038
3059
for ( var i = 0 , l = collection . length ; i < l ; i ++ ) {
3039
- this . buildItem ( collection [ i ] , i )
3060
+ self . buildItem ( collection [ i ] , i )
3040
3061
}
3062
+ if ( ! init ) self . changed ( )
3041
3063
}
3042
3064
} ,
3043
3065
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
+
3044
3082
/**
3045
3083
* Create a new child VM from a data object
3046
3084
* passing along compiler options indicating this
0 commit comments