rename Binding -> Dep

This commit is contained in:
Evan You 2014-11-26 13:05:03 -05:00
parent 57d81efe78
commit 4faf16e281
19 changed files with 111 additions and 113 deletions

View File

@ -18,7 +18,6 @@
"src/api/global.js",
"src/api/lifecycle.js",
"src/batcher.js",
"src/binding.js",
"src/cache.js",
"src/compiler/compile.js",
"src/compiler/transclude.js",
@ -53,6 +52,7 @@
"src/instance/init.js",
"src/instance/scope.js",
"src/observer/array.js",
"src/observer/dep.js",
"src/observer/index.js",
"src/observer/object.js",
"src/parsers/directive.js",

View File

@ -125,7 +125,6 @@ function cleanup (vm) {
vm.$parent =
vm.$root =
vm._children =
vm._bindings =
vm._directives = null
// call the last hook...
vm._isDestroyed = true

View File

@ -1,6 +1,6 @@
var _ = require('../util')
var Observer = require('../observer')
var Binding = require('../binding')
var Dep = require('../observer/dep')
/**
* Setup the scope of an instance, which contains:
@ -197,20 +197,20 @@ exports._initMeta = function () {
*/
exports._defineMeta = function (key, value) {
var binding = new Binding()
var dep = new Dep()
Object.defineProperty(this, key, {
enumerable: true,
configurable: true,
get: function metaGetter () {
if (Observer.target) {
Observer.target.addDep(binding)
Observer.target.addDep(dep)
}
return value
},
set: function metaSetter (val) {
if (val !== value) {
value = val
binding.notify()
dep.notify()
}
}
})

View File

@ -1,18 +1,18 @@
var uid = 0
/**
* A binding is an observable that can have multiple
* A dep is an observable that can have multiple
* directives subscribing to it.
*
* @constructor
*/
function Binding () {
function Dep () {
this.id = ++uid
this.subs = []
}
var p = Binding.prototype
var p = Dep.prototype
/**
* Add a directive subscriber.
@ -47,4 +47,4 @@ p.notify = function () {
}
}
module.exports = Binding
module.exports = Dep

View File

@ -1,6 +1,6 @@
var _ = require('../util')
var config = require('../config')
var Binding = require('../binding')
var Dep = require('./dep')
var arrayMethods = require('./array')
var arrayKeys = Object.getOwnPropertyNames(arrayMethods)
require('./object')
@ -58,7 +58,7 @@ function Observer (value, type) {
this.id = ++uid
this.value = value
this.active = true
this.bindings = []
this.deps = []
_.define(value, '__ob__', this)
if (type === ARRAY) {
var augment = config.proto && _.hasProto
@ -126,10 +126,10 @@ p.walk = function (obj) {
/**
* Try to carete an observer for a child value,
* and if value is array, link binding to the array.
* and if value is array, link dep to the array.
*
* @param {*} val
* @return {Binding|undefined}
* @return {Dep|undefined}
*/
p.observe = function (val) {
@ -160,9 +160,9 @@ p.observeArray = function (items) {
p.convert = function (key, val) {
var ob = this
var childOb = ob.observe(val)
var binding = new Binding()
var dep = new Dep()
if (childOb) {
childOb.bindings.push(binding)
childOb.deps.push(dep)
}
Object.defineProperty(ob.value, key, {
enumerable: true,
@ -171,40 +171,40 @@ p.convert = function (key, val) {
// Observer.target is a watcher whose getter is
// currently being evaluated.
if (ob.active && Observer.target) {
Observer.target.addDep(binding)
Observer.target.addDep(dep)
}
return val
},
set: function (newVal) {
if (newVal === val) return
// remove binding from old value
// remove dep from old value
var oldChildOb = val && val.__ob__
if (oldChildOb) {
var oldBindings = oldChildOb.bindings
oldBindings.splice(oldBindings.indexOf(binding), 1)
var oldDeps = oldChildOb.deps
oldDeps.splice(oldDeps.indexOf(dep), 1)
}
val = newVal
// add binding to new value
// add dep to new value
var newChildOb = ob.observe(newVal)
if (newChildOb) {
newChildOb.bindings.push(binding)
newChildOb.deps.push(dep)
}
binding.notify()
dep.notify()
}
})
}
/**
* Notify change on all self bindings on an observer.
* Notify change on all self deps on an observer.
* This is called when a mutable value mutates. e.g.
* when an Array's mutating methods are called, or an
* Object's $add/$delete are called.
*/
p.notify = function () {
var bindings = this.bindings
for (var i = 0, l = bindings.length; i < l; i++) {
bindings[i].notify()
var deps = this.deps
for (var i = 0, l = deps.length; i < l; i++) {
deps[i].notify()
}
}

View File

@ -46,18 +46,18 @@ function Watcher (vm, expression, cb, filters, needSet, deep) {
var p = Watcher.prototype
/**
* Add a binding dependency to this directive.
* Add a dependency to this directive.
*
* @param {Binding} binding
* @param {Dep} dep
*/
p.addDep = function (binding) {
var id = binding.id
p.addDep = function (dep) {
var id = dep.id
if (!this.newDeps[id]) {
this.newDeps[id] = binding
this.newDeps[id] = dep
if (!this.deps[id]) {
this.deps[id] = binding
binding.addSub(this)
this.deps[id] = dep
dep.addSub(this)
}
}
}

View File

@ -168,7 +168,6 @@ if (_.inBrowser) {
expect(vm.$parent).toBeNull()
expect(vm.$root).toBeNull()
expect(vm._children).toBeNull()
expect(vm._bindings).toBeNull()
expect(vm._directives).toBeNull()
expect(Object.keys(vm._events).length).toBe(0)
})

View File

@ -1,34 +0,0 @@
var Binding = require('../../../src/binding')
describe('Binding', function () {
var b
beforeEach(function () {
b = new Binding()
})
it('addSub', function () {
var sub = {}
b.addSub(sub)
expect(b.subs.length).toBe(1)
expect(b.subs.indexOf(sub)).toBe(0)
})
it('removeSub', function () {
var sub = {}
b.addSub(sub)
b.removeSub(sub)
expect(b.subs.length).toBe(0)
expect(b.subs.indexOf(sub)).toBe(-1)
})
it('notify', function () {
var sub = {
update: jasmine.createSpy('sub')
}
b.addSub(sub)
b.notify()
expect(sub.update).toHaveBeenCalled()
})
})

View File

@ -1,5 +1,5 @@
var Vue = require('../../../src/vue')
var filters = require('../../../src/filters')
var Vue = require('../../../../src/vue')
var filters = require('../../../../src/filters')
describe('Filters', function () {

View File

@ -0,0 +1,34 @@
var Dep = require('../../../../src/observer/dep')
describe('Dep', function () {
var d
beforeEach(function () {
d = new Dep()
})
it('addSub', function () {
var sub = {}
d.addSub(sub)
expect(d.subs.length).toBe(1)
expect(d.subs.indexOf(sub)).toBe(0)
})
it('removeSub', function () {
var sub = {}
d.addSub(sub)
d.removeSub(sub)
expect(d.subs.length).toBe(0)
expect(d.subs.indexOf(sub)).toBe(-1)
})
it('notify', function () {
var sub = {
update: jasmine.createSpy('sub')
}
d.addSub(sub)
d.notify()
expect(sub.update).toHaveBeenCalled()
})
})

View File

@ -1,7 +1,7 @@
var Observer = require('../../../src/observer')
var config = require('../../../src/config')
var Binding = require('../../../src/binding')
var _ = require('../../../src/util')
var Observer = require('../../../../src/observer')
var config = require('../../../../src/config')
var Dep = require('../../../../src/observer/dep')
var _ = require('../../../../src/util')
describe('Observer', function () {
@ -57,9 +57,9 @@ describe('Observer', function () {
// mock a watcher!
var watcher = {
deps: [],
addDep: function (binding) {
this.deps.push(binding)
binding.addSub(this)
addDep: function (dep) {
this.deps.push(dep)
dep.addSub(this)
},
update: jasmine.createSpy()
}
@ -75,8 +75,8 @@ describe('Observer', function () {
var oldA = obj.a
obj.a = { b: 4 }
expect(watcher.update.calls.count()).toBe(2)
expect(oldA.__ob__.bindings.length).toBe(0)
expect(obj.a.__ob__.bindings.length).toBe(1)
expect(oldA.__ob__.deps.length).toBe(0)
expect(obj.a.__ob__.deps.length).toBe(1)
// recollect dep
var oldDeps = watcher.deps
watcher.deps = []
@ -92,22 +92,22 @@ describe('Observer', function () {
it('observing $add/$delete', function () {
var obj = { a: 1 }
var ob = Observer.create(obj)
var binding = new Binding()
ob.bindings.push(binding)
spyOn(binding, 'notify')
var dep = new Dep()
ob.deps.push(dep)
spyOn(dep, 'notify')
obj.$add('b', 2)
expect(obj.b).toBe(2)
expect(binding.notify.calls.count()).toBe(1)
expect(dep.notify.calls.count()).toBe(1)
obj.$delete('a')
expect(obj.hasOwnProperty('a')).toBe(false)
expect(binding.notify.calls.count()).toBe(2)
expect(dep.notify.calls.count()).toBe(2)
// should ignore adding an existing key
obj.$add('b', 3)
expect(obj.b).toBe(2)
expect(binding.notify.calls.count()).toBe(2)
expect(dep.notify.calls.count()).toBe(2)
// should ignore deleting non-existing key
obj.$delete('a')
expect(binding.notify.calls.count()).toBe(2)
expect(dep.notify.calls.count()).toBe(2)
// should work on non-observed objects
var obj2 = { a: 1 }
obj2.$delete('a')
@ -117,9 +117,9 @@ describe('Observer', function () {
it('observing array mutation', function () {
var arr = []
var ob = Observer.create(arr)
var binding = new Binding()
ob.bindings.push(binding)
spyOn(binding, 'notify')
var dep = new Dep()
ob.deps.push(dep)
spyOn(dep, 'notify')
var objs = [{}, {}, {}]
arr.push(objs[0])
arr.pop()
@ -128,7 +128,7 @@ describe('Observer', function () {
arr.splice(0, 0, objs[2])
arr.sort()
arr.reverse()
expect(binding.notify.calls.count()).toBe(7)
expect(dep.notify.calls.count()).toBe(7)
// inserted elements should be observed
objs.forEach(function (obj) {
expect(obj.__ob__ instanceof Observer).toBe(true)
@ -138,16 +138,16 @@ describe('Observer', function () {
it('array $set', function () {
var arr = [1]
var ob = Observer.create(arr)
var binding = new Binding()
ob.bindings.push(binding)
spyOn(binding, 'notify')
var dep = new Dep()
ob.deps.push(dep)
spyOn(dep, 'notify')
arr.$set(0, 2)
expect(arr[0]).toBe(2)
expect(binding.notify.calls.count()).toBe(1)
expect(dep.notify.calls.count()).toBe(1)
// setting out of bound index
arr.$set(2, 3)
expect(arr[2]).toBe(3)
expect(binding.notify.calls.count()).toBe(2)
expect(dep.notify.calls.count()).toBe(2)
})
it('array $remove', function () {
@ -155,23 +155,23 @@ describe('Observer', function () {
var obj1 = arr[0]
var obj2 = arr[1]
var ob = Observer.create(arr)
var binding = new Binding()
ob.bindings.push(binding)
spyOn(binding, 'notify')
var dep = new Dep()
ob.deps.push(dep)
spyOn(dep, 'notify')
// remove by index
arr.$remove(0)
expect(arr.length).toBe(1)
expect(arr[0]).toBe(obj2)
expect(binding.notify.calls.count()).toBe(1)
expect(dep.notify.calls.count()).toBe(1)
// remove by identity, not in array
arr.$remove(obj1)
expect(arr.length).toBe(1)
expect(arr[0]).toBe(obj2)
expect(binding.notify.calls.count()).toBe(1)
expect(dep.notify.calls.count()).toBe(1)
// remove by identity, in array
arr.$remove(obj2)
expect(arr.length).toBe(0)
expect(binding.notify.calls.count()).toBe(2)
expect(dep.notify.calls.count()).toBe(2)
})
it('no proto', function () {
@ -181,22 +181,22 @@ describe('Observer', function () {
var ob = Observer.create(obj)
expect(obj.$add).toBeTruthy()
expect(obj.$delete).toBeTruthy()
var binding = new Binding()
ob.bindings.push(binding)
spyOn(binding, 'notify')
var dep = new Dep()
ob.deps.push(dep)
spyOn(dep, 'notify')
obj.$add('b', 2)
expect(binding.notify).toHaveBeenCalled()
expect(dep.notify).toHaveBeenCalled()
// array
var arr = [1, 2, 3]
var ob2 = Observer.create(arr)
expect(arr.$set).toBeTruthy()
expect(arr.$remove).toBeTruthy()
expect(arr.push).not.toBe([].push)
var binding2 = new Binding()
ob2.bindings.push(binding2)
spyOn(binding2, 'notify')
var dep2 = new Dep()
ob2.deps.push(dep2)
spyOn(dep2, 'notify')
arr.push(1)
expect(binding2.notify).toHaveBeenCalled()
expect(dep2.notify).toHaveBeenCalled()
config.proto = true
})

View File

@ -1,6 +1,6 @@
var Vue = require('../../../src/vue')
var _ = require('../../../src/util')
var transition = require('../../../src/transition')
var Vue = require('../../../../src/vue')
var _ = require('../../../../src/util')
var transition = require('../../../../src/transition')
if (_.inBrowser && !_.isIE9) {
describe('Transition', function () {