Skip to content

Commit

Permalink
refactor Compiler.createBinding
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jan 27, 2014
1 parent 3924044 commit 50a7881
Showing 1 changed file with 70 additions and 61 deletions.
131 changes: 70 additions & 61 deletions src/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -441,30 +441,27 @@ CompilerProto.bindDirective = function (directive) {
*/
CompilerProto.createBinding = function (key, isExp, isFn) {

log(' created binding: ' + key)

var compiler = this,
bindings = compiler.bindings,
computed = compiler.options.computed,
binding = new Binding(compiler, key, isExp, isFn)

if (isExp) {
// a complex expression binding
// we need to generate an anonymous computed property for it
var getter = ExpParser.parse(key, compiler)
if (getter) {
log(' created expression binding: ' + key)
binding.value = isFn
? getter
: { $get: getter }
compiler.markComputed(binding)
compiler.exps.push(binding)
}
// expression bindings are anonymous
compiler.defineExp(key, binding)
} else {
log(' created binding: ' + key)
bindings[key] = binding
// make sure the key exists in the object so it can be observed
// by the Observer!
if (binding.root) {
// this is a root level binding. we need to define getter/setters for it.
compiler.define(key, binding)
if (computed && computed[key]) {
// computed property
compiler.defineComputed(key, binding, computed[key])
} else {
// normal property
compiler.defineProp(key, binding)
}
} else {
// ensure path in data so it can be observed
Observer.ensurePath(compiler.data, key)
Expand All @@ -480,70 +477,82 @@ CompilerProto.createBinding = function (key, isExp, isFn) {
}

/**
* Defines the getter/setter for a root-level binding on the VM
* Define the getter/setter for a root-level property on the VM
* and observe the initial value
*/
CompilerProto.define = function (key, binding) {

log(' defined root binding: ' + key)

CompilerProto.defineProp = function (key, binding) {

var compiler = this,
data = compiler.data,
vm = compiler.vm,
comps = compiler.options.computed,
ob = data.__observer__,
value

if (comps && comps[key]) {
// computed property
value = binding.value = comps[key]
compiler.markComputed(binding)
} else {
if (!(key in data)) {
data[key] = undefined
}
// if the data object is already observed, but the key
// is not observed, we need to add it to the observed keys.
if (ob && !(key in ob.values)) {
Observer.convert(data, key)
}
value = binding.value = data[key]
ob = data.__observer__

// make sure the key is present in data
// so it can be observed
if (!(key in data)) {
data[key] = undefined
}

Object.defineProperty(vm, key, {
get: binding.isComputed
? function () {
return binding.value.$get()
}
: function () {
return compiler.data[key]
},
set: binding.isComputed
? function (val) {
if (binding.value.$set) {
binding.value.$set(val)
}
}
: function (val) {
compiler.data[key] = val
}
// if the data object is already observed, but the key
// is not observed, we need to add it to the observed keys.
if (ob && !(key in ob.values)) {
Observer.convert(data, key)
}

binding.value = data[key]

Object.defineProperty(compiler.vm, key, {
get: function () {
return compiler.data[key]
},
set: function (val) {
compiler.data[key] = val
}
})
}

/**
* Define an expression binding, which is essentially
* an anonymous computed property
*/
CompilerProto.defineExp = function (key, binding) {
var getter = ExpParser.parse(key, this)
if (getter) {
var value = binding.isFn
? getter
: { $get: getter }
this.markComputed(binding, value)
this.exps.push(binding)
}
}

/**
* Define a computed property on the VM
*/
CompilerProto.defineComputed = function (key, binding, value) {
this.markComputed(binding, value)
var def = {
get: binding.value.$get
}
if (binding.value.$set) {
def.set = binding.value.$set
}
Object.defineProperty(this.vm, key, def)
}

/**
* Process a computed property binding
* so its getter/setter are bound to proper context
*/
CompilerProto.markComputed = function (binding) {
var value = binding.value,
vm = this.vm
CompilerProto.markComputed = function (binding, value) {
binding.value = value
binding.isComputed = true
// bind the accessors to the vm
if (!binding.isFn) {
binding.value = {
$get: utils.bind(value.$get, vm)
$get: utils.bind(value.$get, this.vm)
}
if (value.$set) {
binding.value.$set = utils.bind(value.$set, vm)
binding.value.$set = utils.bind(value.$set, this.vm)
}
}
// keep track for dep parsing later
Expand Down

0 comments on commit 50a7881

Please sign in to comment.