@@ -86,26 +86,14 @@ for (var method in extensions) {
86
86
def ( ArrayProxy , method , extensions [ method ] , ! hasProto )
87
87
}
88
88
89
- /**
90
- * Watch an object based on type
91
- */
92
- function watch ( obj , path , observer ) {
93
- var type = typeOf ( obj )
94
- if ( type === 'Object' ) {
95
- watchObject ( obj , path , observer )
96
- } else if ( type === 'Array' ) {
97
- watchArray ( obj , path , observer )
98
- }
99
- }
100
-
101
89
/**
102
90
* Watch an Object, recursive.
103
91
*/
104
92
function watchObject ( obj , path , observer ) {
105
93
for ( var key in obj ) {
106
94
var keyPrefix = key . charAt ( 0 )
107
95
if ( keyPrefix !== '$' && keyPrefix !== '_' ) {
108
- bind ( obj , key , path , observer )
96
+ convert ( obj , key , observer )
109
97
}
110
98
}
111
99
}
@@ -131,33 +119,34 @@ function watchArray (arr, path, observer) {
131
119
* so it emits get/set events.
132
120
* Then watch the value itself.
133
121
*/
134
- function bind ( obj , key , path , observer ) {
122
+ function convert ( obj , key , observer ) {
135
123
var val = obj [ key ] ,
136
- watchable = isWatchable ( val ) ,
137
- values = observer . values ,
138
- fullKey = ( path ? path + '.' : '' ) + key
139
- values [ fullKey ] = val
124
+ values = observer . values
125
+ values [ key ] = val
140
126
// emit set on bind
141
127
// this means when an object is observed it will emit
142
128
// a first batch of set events.
143
- observer . emit ( 'set' , fullKey , val )
129
+ observer . emit ( 'set' , key , val )
144
130
Object . defineProperty ( obj , key , {
145
131
enumerable : true ,
146
132
get : function ( ) {
133
+ var value = values [ key ]
147
134
// only emit get on tip values
148
- if ( depsOb . active && ! watchable ) {
149
- observer . emit ( 'get' , fullKey )
135
+ if ( depsOb . active && ! isWatchable ( value ) ) {
136
+ observer . emit ( 'get' , key )
150
137
}
151
- return values [ fullKey ]
138
+ return value
152
139
} ,
153
140
set : function ( newVal ) {
154
- values [ fullKey ] = newVal
155
- ensurePaths ( key , newVal , values )
156
- observer . emit ( 'set' , fullKey , newVal )
157
- watch ( newVal , fullKey , observer )
141
+ var oldVal = values [ key ]
142
+ unobserve ( oldVal , key , observer )
143
+ values [ key ] = newVal
144
+ ensurePaths ( '' , newVal , oldVal )
145
+ observer . emit ( 'set' , key , newVal )
146
+ observe ( newVal , key , observer )
158
147
}
159
148
} )
160
- watch ( val , fullKey , observer )
149
+ observe ( val , key , observer )
161
150
}
162
151
163
152
/**
@@ -175,14 +164,17 @@ function isWatchable (obj) {
175
164
* the watch conversion and simply emit set event for
176
165
* all of its properties.
177
166
*/
178
- function emitSet ( obj , observer , set ) {
179
- if ( typeOf ( obj ) === 'Array' ) {
180
- set ( 'length' , obj . length )
181
- } else {
182
- var key , val , values = observer . values
183
- for ( key in observer . values ) {
184
- val = values [ key ]
185
- set ( key , val )
167
+ function emitSet ( obj ) {
168
+ var type = typeOf ( obj ) ,
169
+ emitter = obj . __observer__
170
+ if ( type === 'Array' ) {
171
+ emitter . emit ( 'set' , 'length' , obj . length )
172
+ } else if ( type === 'Object' ) {
173
+ var key , val
174
+ for ( key in obj ) {
175
+ val = obj [ key ]
176
+ emitter . emit ( 'set' , key , val )
177
+ emitSet ( val )
186
178
}
187
179
}
188
180
}
@@ -194,10 +186,10 @@ function emitSet (obj, observer, set) {
194
186
* any given path.
195
187
*/
196
188
function ensurePaths ( key , val , paths ) {
197
- key += '. '
189
+ key = key ? key + '.' : ' '
198
190
for ( var path in paths ) {
199
- if ( ! path . indexOf ( key ) ) {
200
- ensurePath ( val , path . replace ( key , '' ) )
191
+ if ( ! key || ! path . indexOf ( key ) ) {
192
+ ensurePath ( val , key ? path . replace ( key , '' ) : path )
201
193
}
202
194
}
203
195
}
@@ -222,68 +214,74 @@ function ensurePath (obj, key) {
222
214
return obj [ sec ]
223
215
}
224
216
225
- module . exports = {
226
-
227
- // used in v-repeat
228
- watchArray : watchArray ,
229
- ensurePath : ensurePath ,
230
- ensurePaths : ensurePaths ,
231
-
232
- /**
233
- * Observe an object with a given path,
234
- * and proxy get/set/mutate events to the provided observer.
235
- */
236
- observe : function ( obj , rawPath , observer ) {
237
- if ( isWatchable ( obj ) ) {
238
- var path = rawPath + '.' ,
239
- ob , alreadyConverted = ! ! obj . __observer__
240
- if ( ! alreadyConverted ) {
241
- def ( obj , '__observer__' , new Emitter ( ) )
242
- }
243
- ob = obj . __observer__
244
- ob . values = ob . values || utils . hash ( )
245
- var proxies = observer . proxies [ path ] = {
246
- get : function ( key ) {
247
- observer . emit ( 'get' , path + key )
248
- } ,
249
- set : function ( key , val ) {
250
- observer . emit ( 'set' , path + key , val )
251
- } ,
252
- mutate : function ( key , val , mutation ) {
253
- // if the Array is a root value
254
- // the key will be null
255
- var fixedPath = key ? path + key : rawPath
256
- observer . emit ( 'mutate' , fixedPath , val , mutation )
257
- // also emit set for Array's length when it mutates
258
- var m = mutation . method
259
- if ( m !== 'sort' && m !== 'reverse' ) {
260
- observer . emit ( 'set' , fixedPath + '.length' , val . length )
261
- }
262
- }
263
- }
264
- ob
265
- . on ( 'get' , proxies . get )
266
- . on ( 'set' , proxies . set )
267
- . on ( 'mutate' , proxies . mutate )
268
- if ( alreadyConverted ) {
269
- emitSet ( obj , ob , proxies . set )
270
- } else {
271
- watch ( obj , null , ob )
217
+ /**
218
+ * Observe an object with a given path,
219
+ * and proxy get/set/mutate events to the provided observer.
220
+ */
221
+ function observe ( obj , rawPath , observer ) {
222
+ if ( ! isWatchable ( obj ) ) return
223
+ var path = rawPath ? rawPath + '.' : '' ,
224
+ ob , alreadyConverted = ! ! obj . __observer__
225
+ if ( ! alreadyConverted ) {
226
+ def ( obj , '__observer__' , new Emitter ( ) )
227
+ }
228
+ ob = obj . __observer__
229
+ ob . values = ob . values || utils . hash ( )
230
+ observer . proxies = observer . proxies || { }
231
+ var proxies = observer . proxies [ path ] = {
232
+ get : function ( key ) {
233
+ observer . emit ( 'get' , path + key )
234
+ } ,
235
+ set : function ( key , val ) {
236
+ observer . emit ( 'set' , path + key , val )
237
+ } ,
238
+ mutate : function ( key , val , mutation ) {
239
+ // if the Array is a root value
240
+ // the key will be null
241
+ var fixedPath = key ? path + key : rawPath
242
+ observer . emit ( 'mutate' , fixedPath , val , mutation )
243
+ // also emit set for Array's length when it mutates
244
+ var m = mutation . method
245
+ if ( m !== 'sort' && m !== 'reverse' ) {
246
+ observer . emit ( 'set' , fixedPath + '.length' , val . length )
272
247
}
273
248
}
274
- } ,
275
-
276
- /**
277
- * Cancel observation, turn off the listeners.
278
- */
279
- unobserve : function ( obj , path , observer ) {
280
- if ( ! obj || ! obj . __observer__ ) return
281
- path = path + '.'
282
- var proxies = observer . proxies [ path ]
283
- obj . __observer__
284
- . off ( 'get' , proxies . get )
285
- . off ( 'set' , proxies . set )
286
- . off ( 'mutate' , proxies . mutate )
287
- observer . proxies [ path ] = null
288
249
}
250
+ ob
251
+ . on ( 'get' , proxies . get )
252
+ . on ( 'set' , proxies . set )
253
+ . on ( 'mutate' , proxies . mutate )
254
+ if ( alreadyConverted ) {
255
+ emitSet ( obj )
256
+ } else {
257
+ var type = typeOf ( obj )
258
+ if ( type === 'Object' ) {
259
+ watchObject ( obj , null , ob )
260
+ } else if ( type === 'Array' ) {
261
+ watchArray ( obj , null , ob )
262
+ }
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Cancel observation, turn off the listeners.
268
+ */
269
+ function unobserve ( obj , path , observer ) {
270
+ if ( ! obj || ! obj . __observer__ ) return
271
+ path = path + '.'
272
+ var proxies = observer . proxies [ path ]
273
+ obj . __observer__
274
+ . off ( 'get' , proxies . get )
275
+ . off ( 'set' , proxies . set )
276
+ . off ( 'mutate' , proxies . mutate )
277
+ observer . proxies [ path ] = null
278
+ }
279
+
280
+ module . exports = {
281
+ observe : observe ,
282
+ unobserve : unobserve ,
283
+ ensurePath : ensurePath ,
284
+ ensurePaths : ensurePaths ,
285
+ // used in v-repeat
286
+ watchArray : watchArray ,
289
287
}
0 commit comments