Skip to content

Commit f2e32ab

Browse files
author
Evan You
committed
Make Observer emit set for all parent objects too
1 parent cc5f98a commit f2e32ab

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

src/compiler.js

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function Compiler (vm, options) {
9696
extend(data, vm)
9797

9898
// observe the data
99-
Observer.observe(data, '', compiler.observer)
99+
compiler.observeData(data)
100100

101101
// for repeated items, create an index binding
102102
// which should be inenumerable but configurable
@@ -106,21 +106,6 @@ function Compiler (vm, options) {
106106
compiler.createBinding('$index')
107107
}
108108

109-
// allow the $data object to be swapped
110-
Object.defineProperty(vm, '$data', {
111-
enumerable: false,
112-
get: function () {
113-
return compiler.data
114-
},
115-
set: function (newData) {
116-
var oldData = compiler.data
117-
Observer.unobserve(oldData, '', compiler.observer)
118-
compiler.data = newData
119-
Observer.copyPaths(newData, oldData)
120-
Observer.observe(newData, '', compiler.observer)
121-
}
122-
})
123-
124109
// now parse the DOM, during which we will create necessary bindings
125110
// and bind the parsed directives
126111
compiler.compile(el, true)
@@ -242,6 +227,44 @@ CompilerProto.setupObserver = function () {
242227
}
243228
}
244229

230+
CompilerProto.observeData = function (data) {
231+
232+
var compiler = this,
233+
observer = compiler.observer
234+
235+
// recursively observe nested properties
236+
Observer.observe(data, '', observer)
237+
238+
// also create binding for top level $data
239+
// so it can be used in templates too
240+
var $dataBinding = compiler.bindings['$data'] = new Binding(compiler, '$data')
241+
$dataBinding.update(data)
242+
243+
// allow $data to be swapped
244+
Object.defineProperty(compiler.vm, '$data', {
245+
enumerable: false,
246+
get: function () {
247+
compiler.observer.emit('get', '$data')
248+
return compiler.data
249+
},
250+
set: function (newData) {
251+
var oldData = compiler.data
252+
Observer.unobserve(oldData, '', observer)
253+
compiler.data = newData
254+
Observer.copyPaths(newData, oldData)
255+
Observer.observe(newData, '', observer)
256+
compiler.observer.emit('set', '$data', newData)
257+
}
258+
})
259+
260+
// emit $data change on all changes
261+
observer.on('set', function (key) {
262+
if (key !== '$data') {
263+
$dataBinding.update(compiler.data)
264+
}
265+
})
266+
}
267+
245268
/**
246269
* Compile a DOM node (recursive)
247270
*/
@@ -463,7 +486,6 @@ CompilerProto.bindDirective = function (directive) {
463486
compiler = compiler || this
464487
binding = compiler.bindings[key] || compiler.createBinding(key)
465488
}
466-
467489
binding.instances.push(directive)
468490
directive.binding = binding
469491

@@ -567,11 +589,10 @@ CompilerProto.defineExp = function (key, binding) {
567589
*/
568590
CompilerProto.defineComputed = function (key, binding, value) {
569591
this.markComputed(binding, value)
570-
var def = {
592+
Object.defineProperty(this.vm, key, {
571593
get: binding.value.$get,
572594
set: binding.value.$set
573-
}
574-
Object.defineProperty(this.vm, key, def)
595+
})
575596
}
576597

577598
/**

src/directive.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ function parseFilter (filter, compiler) {
120120
* during initialization.
121121
*/
122122
DirProto.update = function (value, init) {
123-
if (!init && value === this.value) return
123+
if (!init && value === this.value && utils.typeOf(value) !== 'Object') return
124124
this.value = value
125125
if (this._update) {
126126
this._update(

src/observer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ function observe (obj, rawPath, observer) {
266266
},
267267
set: function (key, val) {
268268
observer.emit('set', path + key, val)
269+
// also notify observer that the object itself chagned
270+
if (rawPath) observer.emit('set', rawPath, obj)
269271
},
270272
mutate: function (key, val, mutation) {
271273
// if the Array is a root value

0 commit comments

Comments
 (0)