Skip to content

Commit 1fb885b

Browse files
author
Evan You
committed
bindings that are not found are now created on current compiler instead of root
1 parent 09b44b8 commit 1fb885b

File tree

4 files changed

+49
-33
lines changed

4 files changed

+49
-33
lines changed

examples/todomvc/js/app.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use strict'
2+
13
var app = new Vue({
24

35
// the root element that will be compiled
@@ -14,9 +16,10 @@ var app = new Vue({
1416
}
1517
},
1618

17-
// the `created` lifecycle hook.
18-
// it will be called when the ViewModel instance is created.
19+
// the `created` lifecycle hook, which will be called
20+
// when the ViewModel instance is created but not yet compiled.
1921
created: function () {
22+
// setup filters
2023
this.filters = {
2124
all: function (todo) { todo.completed; return true },
2225
active: function (todo) { return !todo.completed },
@@ -26,17 +29,16 @@ var app = new Vue({
2629
window.addEventListener('hashchange', function () {
2730
app.updateFilter()
2831
})
29-
this.remaining = this.todos.filter(function (todo) {
30-
return !todo.completed
31-
}).length
32+
// initialize some state
33+
this.newTodo = ''
34+
this.editedTodo = null
35+
this.remaining = this.todos.filter(this.filters.active).length
3236
},
3337

3438
// data
3539
data: {
36-
3740
// fetch the saved todos from localStorage
3841
todos: todoStorage.fetch(),
39-
4042
// a computed property with custom getter/setter
4143
allDone: {
4244
$get: function () {

src/compiler.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -412,20 +412,24 @@ CompilerProto.bindDirective = function (directive) {
412412
if (directive.isExp) {
413413
// expression bindings are always created on current compiler
414414
binding = compiler.createBinding(key, true, directive.isFn)
415-
} else if (
416-
hasOwn.call(compiler.data, baseKey) ||
417-
hasOwn.call(compiler.vm, baseKey)
418-
) {
419-
// If the directive's compiler's VM has the base key,
420-
// it belongs here. Create the binding if it's not created already.
421-
binding = hasOwn.call(compiler.bindings, key)
422-
? compiler.bindings[key]
423-
: compiler.createBinding(key)
424415
} else {
425-
// due to prototypal inheritance of bindings, if a key doesn't exist
426-
// on the bindings object, then it doesn't exist in the whole
427-
// prototype chain. In this case we create the new binding at the root level.
428-
binding = compiler.bindings[key] || compiler.rootCompiler.createBinding(key)
416+
// recursively locate where to place the binding
417+
while (compiler) {
418+
if (
419+
hasOwn.call(compiler.data, baseKey) ||
420+
hasOwn.call(compiler.vm, baseKey)
421+
) {
422+
// If a compiler has the base key, the directive should
423+
// belong to it. Create the binding if it's not created already.
424+
binding = hasOwn.call(compiler.bindings, key)
425+
? compiler.bindings[key]
426+
: compiler.createBinding(key)
427+
break
428+
} else {
429+
compiler = compiler.parentCompiler
430+
}
431+
}
432+
if (!binding) binding = this.createBinding(key)
429433
}
430434

431435
binding.instances.push(directive)

src/exp-parser.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,32 +53,38 @@ function getVariables (code) {
5353
* final resolved vm.
5454
*/
5555
function getRel (path, compiler) {
56-
var rel = '',
57-
vm = compiler.vm,
58-
dot = path.indexOf('.'),
59-
key = dot > -1
56+
var rel = '',
57+
has = false,
58+
nest = 0,
59+
vm = compiler.vm,
60+
dot = path.indexOf('.'),
61+
key = dot > -1
6062
? path.slice(0, dot)
6163
: path
6264
while (true) {
6365
if (
6466
hasOwn.call(vm.$data, key) ||
6567
hasOwn.call(vm, key)
6668
) {
69+
has = true
6770
break
6871
} else {
6972
if (vm.$parent) {
7073
vm = vm.$parent
71-
rel += '$parent.'
74+
nest++
7275
} else {
7376
break
7477
}
7578
}
7679
}
77-
compiler = vm.$compiler
78-
if (
79-
!hasOwn.call(compiler.bindings, path) &&
80-
path.charAt(0) !== '$'
81-
) {
80+
if (has) {
81+
while (nest--) {
82+
rel += '$parent.'
83+
}
84+
if (!hasOwn.call(vm.$compiler.bindings, path) && path.charAt(0) !== '$') {
85+
vm.$compiler.createBinding(path)
86+
}
87+
} else {
8288
compiler.createBinding(path)
8389
}
8490
return rel

test/unit/specs/exp-parser.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,18 @@ describe('UNIT: Expression Parser', function () {
7575
function describeCase (testCase) {
7676
describe(testCase.exp, function () {
7777

78+
function createBinding (path) {
79+
caughtMissingPaths.push(path)
80+
}
81+
7882
var caughtMissingPaths = [],
7983
compilerMock = {
84+
createBinding: createBinding,
8085
vm:{
8186
$data: {},
8287
$compiler:{
8388
bindings:{},
84-
createBinding: function (path) {
85-
caughtMissingPaths.push(path)
86-
}
89+
createBinding: createBinding
8790
}
8891
}
8992
},
@@ -118,6 +121,7 @@ describe('UNIT: Expression Parser', function () {
118121
warned = true
119122
}
120123
ExpParser.parse('a + "fsef', {
124+
createBinding: function () {},
121125
vm: {
122126
$compiler: {
123127
bindings: {},

0 commit comments

Comments
 (0)