Skip to content

Commit a1582e4

Browse files
committed
allow child VMs $data to be swapped
1 parent 7c1d196 commit a1582e4

File tree

6 files changed

+36
-22
lines changed

6 files changed

+36
-22
lines changed

examples/todomvc/js/app.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
Vue.config({debug:true})
2-
31
var filters = {
42
all: function () { return true },
53
active: function (completed) { return !completed },

src/compiler.js

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function Compiler (vm, options) {
3434
var data = compiler.data = options.data || {}
3535
utils.processOptions(options)
3636
extend(compiler, options.compilerOptions)
37-
extend(vm, options.data, true)
37+
extend(vm, data, true)
3838
extend(vm, options.methods, true)
3939

4040
// initialize element
@@ -44,7 +44,6 @@ function Compiler (vm, options) {
4444
compiler.vm = vm
4545
def(vm, '$', makeHash())
4646
def(vm, '$el', el)
47-
def(vm, '$data', data)
4847
def(vm, '$compiler', compiler)
4948

5049
// keep track of directives and expressions
@@ -83,15 +82,13 @@ function Compiler (vm, options) {
8382

8483
// setup observer
8584
compiler.setupObserver()
86-
8785
// beforeCompile hook
8886
compiler.execHook('beforeCompile', 'created')
8987
// the user might have set some props on the vm
9088
// so copy it back to the data...
9189
extend(data, vm)
9290
// observe the data
9391
Observer.observe(data, '', compiler.observer)
94-
9592
// for repeated items, create an index binding
9693
// which should be inenumerable but configurable
9794
if (compiler.repeat) {
@@ -100,16 +97,27 @@ function Compiler (vm, options) {
10097
compiler.createBinding('$index')
10198
}
10299

100+
Object.defineProperty(vm, '$data', {
101+
enumerable: false,
102+
get: function () {
103+
return compiler.data
104+
},
105+
set: function (newData) {
106+
var oldData = compiler.data
107+
Observer.unobserve(oldData, '', compiler.observer)
108+
compiler.data = newData
109+
Observer.copyPaths(newData, oldData)
110+
Observer.observe(newData, '', compiler.observer)
111+
}
112+
})
113+
103114
// now parse the DOM, during which we will create necessary bindings
104115
// and bind the parsed directives
105116
compiler.compile(el, true)
106-
107117
// extract dependencies for computed properties
108118
if (computed.length) DepsParser.parse(computed)
109-
110119
// done!
111120
compiler.init = false
112-
113121
// post compile / ready hook
114122
compiler.execHook('afterCompile', 'ready')
115123
}
@@ -409,7 +417,6 @@ CompilerProto.bindDirective = function (directive) {
409417
CompilerProto.createBinding = function (key, isExp, isFn) {
410418

411419
var compiler = this,
412-
data = compiler.data,
413420
bindings = compiler.bindings,
414421
binding = new Binding(compiler, key, isExp, isFn)
415422

@@ -435,7 +442,7 @@ CompilerProto.createBinding = function (key, isExp, isFn) {
435442
compiler.define(key, binding)
436443
} else {
437444
// ensure path in data so it can be observed
438-
Observer.ensurePath(data, key)
445+
Observer.ensurePath(compiler.data, key)
439446
var parentKey = key.slice(0, key.lastIndexOf('.'))
440447
if (!hasOwn.call(bindings, parentKey)) {
441448
// this is a nested value binding, but the binding for its parent
@@ -477,19 +484,19 @@ CompilerProto.define = function (key, binding) {
477484
Object.defineProperty(vm, key, {
478485
get: binding.isComputed
479486
? function () {
480-
return data[key].$get()
487+
return compiler.data[key].$get()
481488
}
482489
: function () {
483-
return data[key]
490+
return compiler.data[key]
484491
},
485492
set: binding.isComputed
486493
? function (val) {
487-
if (data[key].$set) {
488-
data[key].$set(val)
494+
if (compiler.data[key].$set) {
495+
compiler.data[key].$set(val)
489496
}
490497
}
491498
: function (val) {
492-
data[key] = val
499+
compiler.data[key] = val
493500
}
494501
})
495502
}

src/directives/component.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module.exports = {
1212
if (!this.component) {
1313
this.build(value)
1414
} else {
15-
this.component.model = value
15+
this.component.$data = value
1616
}
1717
},
1818

src/observer.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ function isWatchable (obj) {
175175
*/
176176
function emitSet (obj) {
177177
var type = typeOf(obj),
178-
emitter = obj.__observer__
178+
emitter = obj && obj.__observer__
179179
if (type === ARRAY) {
180180
emitter.emit('set', 'length', obj.length)
181181
} else if (type === OBJECT) {
@@ -292,7 +292,7 @@ function observe (obj, rawPath, observer) {
292292
*/
293293
function unobserve (obj, path, observer) {
294294
if (!obj || !obj.__observer__) return
295-
path = path + '.'
295+
path = path ? path + '.' : ''
296296
var proxies = observer.proxies[path]
297297
if (!proxies) return
298298
obj.__observer__
@@ -307,6 +307,6 @@ module.exports = {
307307
unobserve : unobserve,
308308
ensurePath : ensurePath,
309309
convert : convert,
310-
// used in v-repeat
310+
copyPaths : copyPaths,
311311
watchArray : watchArray,
312312
}

test/functional/fixtures/extend.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
log.textContent += ' C ready'
6262
}
6363
})
64-
new T({
64+
var test = new T({
6565
el: '#test',
6666
data: {
6767
dirMsg: 'directive',

test/functional/specs/extend.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
casper.test.begin('Encapsulation & Inheritance', 7, function (test) {
1+
casper.test.begin('Encapsulation & Inheritance', 8, function (test) {
22

33
casper
44
.start('./fixtures/extend.html', function () {
@@ -11,6 +11,15 @@ casper.test.begin('Encapsulation & Inheritance', 7, function (test) {
1111

1212
test.assertSelectorHasText('#log', 'T created T ready T created C created T ready C ready', 'hook inheritance works')
1313
test.assertSelectorHasText('.cvm', 'component works', 'Child should have access to Parent options')
14+
15+
this.evaluate(function () {
16+
test.vmData = {
17+
selfMsg: 'replacing $data ',
18+
msg: 'also works'
19+
}
20+
})
21+
22+
test.assertSelectorHasText('.vm-w-model', 'replacing $data also works')
1423
})
1524
.run(function () {
1625
test.done()

0 commit comments

Comments
 (0)