Skip to content

Commit f3af959

Browse files
committed
Collect dependencies on all types
Previously dependencies (get events) are only collected from tip values - this prevents objects being collected as dependency. The issue in #178 is that the user begins a value as non-object, but has a binding somewhere that indicates the value can be an object later. The observer converts the value to an object implicitly, causing expressions not picking it up as dependency. This change makes the observer emit get events regardless of type. Also utils.set and get have been fixed to check for both null and undefined.
1 parent 3df6343 commit f3af959

File tree

5 files changed

+44
-36
lines changed

5 files changed

+44
-36
lines changed

src/deps-parser.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,15 @@ function catchDeps (binding) {
1414
binding.deps = []
1515
catcher.on('get', function (dep) {
1616
var has = got[dep.key]
17-
if (has && has.compiler === dep.compiler) return
17+
if (
18+
// avoid duplicate bindings
19+
(has && has.compiler === dep.compiler) ||
20+
// avoid repeated items as dependency
21+
// since all inside changes trigger array change too
22+
(dep.compiler.repeat && dep.compiler.parent === binding.compiler)
23+
) {
24+
return
25+
}
1826
got[dep.key] = dep
1927
utils.log(' - ' + dep.key)
2028
binding.deps.push(dep)

src/observer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ function convertKey (obj, key) {
287287
get: function () {
288288
var value = values[key]
289289
// only emit get on tip values
290-
if (pub.shouldGet && typeOf(value) !== OBJECT) {
290+
if (pub.shouldGet) {
291291
emitter.emit('get', key)
292292
}
293293
return value

src/utils.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ var utils = module.exports = {
1313
* get a value from an object keypath
1414
*/
1515
get: function (obj, key) {
16+
/* jshint eqeqeq: false */
1617
if (key.indexOf('.') < 0) {
1718
return obj[key]
1819
}
1920
var path = key.split('.'),
2021
d = -1, l = path.length
21-
while (++d < l && obj !== undefined) {
22+
while (++d < l && obj != null) {
2223
obj = obj[path[d]]
2324
}
2425
return obj
@@ -28,14 +29,15 @@ var utils = module.exports = {
2829
* set a value to an object keypath
2930
*/
3031
set: function (obj, key, val) {
32+
/* jshint eqeqeq: false */
3133
if (key.indexOf('.') < 0) {
3234
obj[key] = val
3335
return
3436
}
3537
var path = key.split('.'),
3638
d = -1, l = path.length - 1
3739
while (++d < l) {
38-
if (obj[path[d]] === undefined) {
40+
if (obj[path[d]] == null) {
3941
obj[path[d]] = {}
4042
}
4143
obj = obj[path[d]]

test/unit/specs/deps-parser.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ describe('Dependency Parser', function () {
1717
depId: ~~(Math.random() * i),
1818
deps: [],
1919
subs: [],
20+
compiler: {},
2021
value: {
2122
$get: function () {
2223
if (i > 0) {

test/unit/specs/observer.js

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,38 @@ describe('Observer', function () {
4242
path: 'test'
4343
}))
4444

45-
it('should emit get events on tip values', function () {
45+
it('should emit get events', function () {
4646
Observer.shouldGet = true
47-
getTestFactory({
48-
obj: { a: 1, b: { c: 2 } },
49-
expects: [
47+
48+
var ob = new Emitter(),
49+
i = 0,
50+
obj = { a: 1, b: { c: 2 } },
51+
gets = [
52+
'a',
53+
'b.c'
54+
],
55+
expects = [
5056
'test.a',
57+
'test.b',
5158
'test.b.c'
52-
],
53-
path: 'test'
54-
})()
59+
]
60+
Observer.observe(obj, 'test', ob)
61+
ob.on('get', function (key) {
62+
var expected = expects[i]
63+
assert.strictEqual(key, expected)
64+
i++
65+
})
66+
gets.forEach(function (key) {
67+
var path = key.split('.'),
68+
j = 0,
69+
data = obj
70+
while (j < path.length) {
71+
data = data[path[j]]
72+
j++
73+
}
74+
})
75+
assert.strictEqual(i, expects.length)
76+
5577
Observer.shouldGet = false
5678
})
5779

@@ -505,29 +527,4 @@ describe('Observer', function () {
505527
}
506528
}
507529

508-
function getTestFactory (opts) {
509-
return function () {
510-
var ob = new Emitter(),
511-
i = 0,
512-
obj = opts.obj,
513-
expects = opts.expects
514-
Observer.observe(obj, opts.path, ob)
515-
ob.on('get', function (key) {
516-
var expected = expects[i]
517-
assert.strictEqual(key, expected)
518-
i++
519-
})
520-
expects.forEach(function (key) {
521-
var path = key.split('.'),
522-
j = 1,
523-
data = obj
524-
while (j < path.length) {
525-
data = data[path[j]]
526-
j++
527-
}
528-
})
529-
assert.strictEqual(i, expects.length)
530-
}
531-
}
532-
533530
})

0 commit comments

Comments
 (0)