silk-gui
Version:
GUI for developers and Node OS
86 lines (75 loc) • 2.06 kB
JavaScript
var _ = require('../util')
var Watcher = require('../watcher')
var expParser = require('../parsers/expression')
var literalRE = /^(true|false|\s?('[^']*'|"[^"]")\s?)$/
module.exports = {
priority: 900,
bind: function () {
var child = this.vm
var parent = child.$parent
var childKey = this.arg || '$data'
var parentKey = this.expression
if (this.el && this.el !== child.$el) {
_.warn(
'v-with can only be used on instance root elements.'
)
} else if (!parent) {
_.warn(
'v-with must be used on an instance with a parent.'
)
} else if (literalRE.test(parentKey)) {
// no need to setup watchers for literal bindings
if (!this.arg) {
_.warn(
'v-with cannot bind literal value as $data: ' +
parentKey
)
} else {
var value = expParser.parse(parentKey).get()
child.$set(childKey, value)
}
} else {
// simple lock to avoid circular updates.
// without this it would stabilize too, but this makes
// sure it doesn't cause other watchers to re-evaluate.
var locked = false
var lock = function () {
locked = true
_.nextTick(unlock)
}
var unlock = function () {
locked = false
}
this.parentWatcher = new Watcher(
parent,
parentKey,
function (val) {
if (!locked) {
lock()
child.$set(childKey, val)
}
}
)
// set the child initial value first, before setting
// up the child watcher to avoid triggering it
// immediately.
child.$set(childKey, this.parentWatcher.value)
this.childWatcher = new Watcher(
child,
childKey,
function (val) {
if (!locked) {
lock()
parent.$set(parentKey, val)
}
}
)
}
},
unbind: function () {
if (this.parentWatcher) {
this.parentWatcher.teardown()
this.childWatcher.teardown()
}
}
}