Skip to content

Commit 69fdf54

Browse files
committed
make v-with two-way again
1 parent 43fb9c9 commit 69fdf54

File tree

1 file changed

+49
-23
lines changed

1 file changed

+49
-23
lines changed

src/directives/with.js

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,67 @@ module.exports = {
66
priority: 900,
77

88
bind: function () {
9-
var vm = this.vm
10-
if (this.el !== vm.$el) {
9+
10+
var child = this.vm
11+
var parent = child.$parent
12+
var childKey = this.arg || '$data'
13+
var parentKey = this.expression
14+
15+
if (this.el !== child.$el) {
1116
_.warn(
1217
'v-with can only be used on instance root elements.'
1318
)
14-
} else if (!vm.$parent) {
19+
} else if (!parent) {
1520
_.warn(
1621
'v-with must be used on an instance with a parent.'
1722
)
1823
} else {
19-
var key = this.arg
20-
this.watcher = new Watcher(
21-
vm.$parent,
22-
this.expression,
23-
key
24-
? function (val) {
25-
vm.$set(key, val)
26-
}
27-
: function (val) {
28-
vm.$data = val
29-
}
30-
)
31-
// initial set
32-
var initialVal = this.watcher.value
33-
if (key) {
34-
vm.$set(key, initialVal)
35-
} else {
36-
vm.$data = initialVal
24+
25+
// simple lock to avoid circular updates.
26+
// without this it would stabilize too, but this makes
27+
// sure it doesn't cause other watchers to re-evaluate.
28+
var locked = false
29+
var lock = function () {
30+
locked = true
31+
_.nextTick(unlock)
32+
}
33+
var unlock = function () {
34+
locked = false
3735
}
36+
37+
this.parentWatcher = new Watcher(
38+
parent,
39+
parentKey,
40+
function (val) {
41+
if (!locked) {
42+
lock()
43+
child.$set(childKey, val)
44+
}
45+
}
46+
)
47+
48+
// set the child initial value first, before setting
49+
// up the child watcher to avoid triggering it
50+
// immediately.
51+
child.$set(childKey, this.parentWatcher.value)
52+
53+
this.childWatcher = new Watcher(
54+
child,
55+
childKey,
56+
function (val) {
57+
if (!locked) {
58+
lock()
59+
parent.$set(parentKey, val)
60+
}
61+
}
62+
)
3863
}
3964
},
4065

4166
unbind: function () {
42-
if (this.watcher) {
43-
this.watcher.teardown()
67+
if (this.parentWatcher) {
68+
this.parentWatcher.teardown()
69+
this.childWatcher.teardown()
4470
}
4571
}
4672

0 commit comments

Comments
 (0)