@@ -32,7 +32,7 @@ var ArrayProxy = Object.create(Array.prototype)
3232methods . forEach ( function ( method ) {
3333 def ( ArrayProxy , method , function ( ) {
3434 var result = Array . prototype [ method ] . apply ( this , arguments )
35- this . __observer__ . emit ( 'mutate' , this . __observer__ . path , this , {
35+ this . __observer__ . emit ( 'mutate' , null , this , {
3636 method : method ,
3737 args : slice . call ( arguments ) ,
3838 result : result
@@ -109,13 +109,12 @@ function watchObject (obj) {
109109 * Watch an Array, overload mutation methods
110110 * and add augmentations by intercepting the prototype chain
111111 */
112- function watchArray ( arr , path ) {
112+ function watchArray ( arr ) {
113113 var observer = arr . __observer__
114114 if ( ! observer ) {
115115 observer = new Emitter ( )
116116 def ( arr , '__observer__' , observer )
117117 }
118- observer . path = path
119118 if ( hasProto ) {
120119 arr . __proto__ = ArrayProxy
121120 } else {
@@ -252,46 +251,61 @@ function ensurePath (obj, key) {
252251 * Observe an object with a given path,
253252 * and proxy get/set/mutate events to the provided observer.
254253 */
255- function observe ( obj , rawPath , observer ) {
254+ function observe ( obj , rawPath , parentOb ) {
255+
256256 if ( ! isWatchable ( obj ) ) return
257+
257258 var path = rawPath ? rawPath + '.' : '' ,
258- ob , alreadyConverted = ! ! obj . __observer__
259+ alreadyConverted = ! ! obj . __observer__ ,
260+ childOb
261+
259262 if ( ! alreadyConverted ) {
260263 def ( obj , '__observer__' , new Emitter ( ) )
261264 }
262- ob = obj . __observer__
263- ob . values = ob . values || utils . hash ( )
264- observer . proxies = observer . proxies || { }
265- var proxies = observer . proxies [ path ] = {
265+
266+ childOb = obj . __observer__
267+ childOb . values = childOb . values || utils . hash ( )
268+
269+ // setup proxy listeners on the parent observer.
270+ // we need to keep reference to them so that they
271+ // can be removed when the object is un-observed.
272+ parentOb . proxies = parentOb . proxies || { }
273+ var proxies = parentOb . proxies [ path ] = {
266274 get : function ( key ) {
267- observer . emit ( 'get' , path + key )
275+ parentOb . emit ( 'get' , path + key )
268276 } ,
269277 set : function ( key , val , propagate ) {
270- observer . emit ( 'set' , path + key , val )
278+ parentOb . emit ( 'set' , path + key , val )
271279 // also notify observer that the object itself changed
272280 // but only do so when it's a immediate property. this
273281 // avoids duplicate event firing.
274282 if ( rawPath && propagate ) {
275- observer . emit ( 'set' , rawPath , obj , true )
283+ parentOb . emit ( 'set' , rawPath , obj , true )
276284 }
277285 } ,
278286 mutate : function ( key , val , mutation ) {
279287 // if the Array is a root value
280288 // the key will be null
281289 var fixedPath = key ? path + key : rawPath
282- observer . emit ( 'mutate' , fixedPath , val , mutation )
290+ parentOb . emit ( 'mutate' , fixedPath , val , mutation )
283291 // also emit set for Array's length when it mutates
284292 var m = mutation . method
285293 if ( m !== 'sort' && m !== 'reverse' ) {
286- observer . emit ( 'set' , fixedPath + '.length' , val . length )
294+ parentOb . emit ( 'set' , fixedPath + '.length' , val . length )
287295 }
288296 }
289297 }
290- ob
298+
299+ // attach the listeners to the child observer.
300+ // now all the events will propagate upwards.
301+ childOb
291302 . on ( 'get' , proxies . get )
292303 . on ( 'set' , proxies . set )
293304 . on ( 'mutate' , proxies . mutate )
305+
294306 if ( alreadyConverted ) {
307+ // for objects that have already been converted,
308+ // emit set events for everything inside
295309 emitSet ( obj )
296310 } else {
297311 var type = typeOf ( obj )
@@ -307,14 +321,20 @@ function observe (obj, rawPath, observer) {
307321 * Cancel observation, turn off the listeners.
308322 */
309323function unobserve ( obj , path , observer ) {
324+
310325 if ( ! obj || ! obj . __observer__ ) return
326+
311327 path = path ? path + '.' : ''
312328 var proxies = observer . proxies [ path ]
313329 if ( ! proxies ) return
330+
331+ // turn off listeners
314332 obj . __observer__
315333 . off ( 'get' , proxies . get )
316334 . off ( 'set' , proxies . set )
317335 . off ( 'mutate' , proxies . mutate )
336+
337+ // remove reference
318338 observer . proxies [ path ] = null
319339}
320340
0 commit comments