@@ -6,41 +6,67 @@ module.exports = {
6
6
priority : 900 ,
7
7
8
8
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 ) {
11
16
_ . warn (
12
17
'v-with can only be used on instance root elements.'
13
18
)
14
- } else if ( ! vm . $ parent) {
19
+ } else if ( ! parent ) {
15
20
_ . warn (
16
21
'v-with must be used on an instance with a parent.'
17
22
)
18
23
} 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
37
35
}
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
+ )
38
63
}
39
64
} ,
40
65
41
66
unbind : function ( ) {
42
- if ( this . watcher ) {
43
- this . watcher . teardown ( )
67
+ if ( this . parentWatcher ) {
68
+ this . parentWatcher . teardown ( )
69
+ this . childWatcher . teardown ( )
44
70
}
45
71
}
46
72
0 commit comments