Skip to content

Commit 9a45f63

Browse files
committed
clean up get binding owner compiler logic
1 parent 1fb885b commit 9a45f63

File tree

4 files changed

+53
-80
lines changed

4 files changed

+53
-80
lines changed

src/compiler.js

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,30 +44,23 @@ function Compiler (vm, options) {
4444

4545
// set compiler properties
4646
compiler.vm = vm
47+
compiler.bindings = makeHash()
4748
compiler.dirs = []
4849
compiler.exps = []
4950
compiler.computed = []
5051
compiler.childCompilers = []
5152
compiler.emitter = new Emitter()
5253

53-
// inherit parent bindings
54-
var parent = compiler.parentCompiler
55-
compiler.bindings = parent
56-
? Object.create(parent.bindings)
57-
: makeHash()
58-
compiler.rootCompiler = parent
59-
? getRoot(parent)
60-
: compiler
61-
6254
// set inenumerable VM properties
6355
def(vm, '$', makeHash())
6456
def(vm, '$el', el)
6557
def(vm, '$compiler', compiler)
66-
def(vm, '$root', compiler.rootCompiler.vm)
58+
def(vm, '$root', getRoot(compiler).vm)
6759

6860
// set parent VM
6961
// and register child id on parent
70-
var childId = utils.attr(el, 'component-id')
62+
var parent = compiler.parentCompiler,
63+
childId = utils.attr(el, 'component-id')
7164
if (parent) {
7265
parent.childCompilers.push(compiler)
7366
def(vm, '$parent', parent.vm)
@@ -204,7 +197,7 @@ CompilerProto.setupObserver = function () {
204197
})
205198

206199
function check (key) {
207-
if (!hasOwn.call(bindings, key)) {
200+
if (!bindings[key]) {
208201
compiler.createBinding(key)
209202
}
210203
}
@@ -405,31 +398,23 @@ CompilerProto.bindDirective = function (directive) {
405398

406399
// otherwise, we got more work to do...
407400
var binding,
408-
compiler = this,
409-
key = directive.key,
410-
baseKey = key.split('.')[0]
401+
compiler = this,
402+
key = directive.key
411403

412404
if (directive.isExp) {
413405
// expression bindings are always created on current compiler
414406
binding = compiler.createBinding(key, true, directive.isFn)
415407
} else {
416-
// recursively locate where to place the binding
408+
// recursively locate which compiler owns the binding
417409
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)
410+
if (compiler.hasKey(key)) {
427411
break
428412
} else {
429413
compiler = compiler.parentCompiler
430414
}
431415
}
432-
if (!binding) binding = this.createBinding(key)
416+
compiler = compiler || this
417+
binding = compiler.bindings[key] || compiler.createBinding(key)
433418
}
434419

435420
binding.instances.push(directive)
@@ -484,7 +469,7 @@ CompilerProto.createBinding = function (key, isExp, isFn) {
484469
// ensure path in data so it can be observed
485470
Observer.ensurePath(compiler.data, key)
486471
var parentKey = key.slice(0, key.lastIndexOf('.'))
487-
if (!hasOwn.call(bindings, parentKey)) {
472+
if (!bindings[parentKey]) {
488473
// this is a nested value binding, but the binding for its parent
489474
// has not been created yet. We better create that one too.
490475
compiler.createBinding(parentKey)
@@ -585,6 +570,15 @@ CompilerProto.execHook = function (id, alt) {
585570
}
586571
}
587572

573+
/**
574+
* Check if a compiler's data contains a keypath
575+
*/
576+
CompilerProto.hasKey = function (key) {
577+
var baseKey = key.split('.')[0]
578+
return hasOwn.call(this.data, baseKey) ||
579+
hasOwn.call(this.vm, baseKey)
580+
}
581+
588582
/**
589583
* Unbind and remove element
590584
*/
@@ -626,8 +620,8 @@ CompilerProto.destroy = function () {
626620

627621
// unbind/unobserve all own bindings
628622
for (key in bindings) {
629-
if (hasOwn.call(bindings, key)) {
630-
binding = bindings[key]
623+
binding = bindings[key]
624+
if (binding) {
631625
if (binding.root) {
632626
Observer.unobserve(binding.value, binding.key, compiler.observer)
633627
}

src/exp-parser.js

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
var utils = require('./utils'),
2-
hasOwn = Object.prototype.hasOwnProperty,
32
stringSaveRE = /"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,
43
stringRestoreRE = /"(\d+)"/g
54

@@ -54,38 +53,25 @@ function getVariables (code) {
5453
*/
5554
function getRel (path, compiler) {
5655
var rel = '',
57-
has = false,
58-
nest = 0,
59-
vm = compiler.vm,
60-
dot = path.indexOf('.'),
61-
key = dot > -1
62-
? path.slice(0, dot)
63-
: path
64-
while (true) {
65-
if (
66-
hasOwn.call(vm.$data, key) ||
67-
hasOwn.call(vm, key)
68-
) {
69-
has = true
56+
dist = 0,
57+
self = compiler
58+
while (compiler) {
59+
if (compiler.hasKey(path)) {
7060
break
7161
} else {
72-
if (vm.$parent) {
73-
vm = vm.$parent
74-
nest++
75-
} else {
76-
break
77-
}
62+
compiler = compiler.parentCompiler
63+
dist++
7864
}
7965
}
80-
if (has) {
81-
while (nest--) {
66+
if (compiler) {
67+
while (dist--) {
8268
rel += '$parent.'
8369
}
84-
if (!hasOwn.call(vm.$compiler.bindings, path) && path.charAt(0) !== '$') {
85-
vm.$compiler.createBinding(path)
70+
if (!compiler.bindings[path] && path.charAt(0) !== '$') {
71+
compiler.createBinding(path)
8672
}
8773
} else {
88-
compiler.createBinding(path)
74+
self.createBinding(path)
8975
}
9076
return rel
9177
}

test/unit/specs/exp-parser.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ describe('UNIT: Expression Parser', function () {
8282
var caughtMissingPaths = [],
8383
compilerMock = {
8484
createBinding: createBinding,
85+
hasKey: function () {},
8586
vm:{
8687
$data: {},
8788
$compiler:{
@@ -120,12 +121,14 @@ describe('UNIT: Expression Parser', function () {
120121
utils.warn = function () {
121122
warned = true
122123
}
124+
function noop () {}
123125
ExpParser.parse('a + "fsef', {
124-
createBinding: function () {},
126+
createBinding: noop,
127+
hasKey: noop,
125128
vm: {
126129
$compiler: {
127130
bindings: {},
128-
createBinding: function () {}
131+
createBinding: noop
129132
},
130133
$data: {}
131134
}

test/unit/specs/viewmodel.js

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,7 @@ describe('UNIT: ViewModel', function () {
371371
expUnbindCalled = false,
372372
bindingUnbindCalled = false,
373373
unobserveCalled = 0,
374-
elRemoved = false,
375-
externalBindingUnbindCalled = false
374+
elRemoved = false
376375

377376
var dirMock = {
378377
binding: {
@@ -385,26 +384,21 @@ describe('UNIT: ViewModel', function () {
385384
}
386385
dirMock.binding.instances.push(dirMock)
387386

388-
var bindingsMock = Object.create({
389-
'test2': {
390-
unbind: function () {
391-
externalBindingUnbindCalled = true
392-
}
393-
}
394-
})
395-
bindingsMock.test = {
396-
root: true,
397-
key: 'test',
398-
value: {
399-
__observer__: {
400-
off: function () {
401-
unobserveCalled++
402-
return this
387+
var bindingsMock = {
388+
test: {
389+
root: true,
390+
key: 'test',
391+
value: {
392+
__observer__: {
393+
off: function () {
394+
unobserveCalled++
395+
return this
396+
}
403397
}
398+
},
399+
unbind: function () {
400+
bindingUnbindCalled = true
404401
}
405-
},
406-
unbind: function () {
407-
bindingUnbindCalled = true
408402
}
409403
}
410404

@@ -487,10 +481,6 @@ describe('UNIT: ViewModel', function () {
487481
assert.strictEqual(unobserveCalled, 3)
488482
})
489483

490-
it('should not unbind external bindings', function () {
491-
assert.notOk(externalBindingUnbindCalled)
492-
})
493-
494484
it('should remove self from parentCompiler', function () {
495485
var parent = compilerMock.parentCompiler
496486
assert.ok(parent.childCompilers.indexOf(compilerMock), -1)

0 commit comments

Comments
 (0)