Skip to content

Commit

Permalink
Async fixes
Browse files Browse the repository at this point in the history
- vm.$watch is now async
- v-model now unlocks async (so it is properly locked during async update)
- expose Vue.nextTick
  • Loading branch information
yyx990803 committed Jan 2, 2014
1 parent 6cbb9fa commit c71a908
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 27 deletions.
4 changes: 3 additions & 1 deletion src/directives/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ module.exports = {
// no filters, don't let it trigger update()
self.lock = true
self.vm.$set(self.key, el[attr])
self.lock = false
utils.nextTick(function () {
self.lock = false
})
}
el.addEventListener(self.event, self.set)

Expand Down
1 change: 1 addition & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ ViewModel.transition = function (id, transition) {
}

ViewModel.extend = extend
ViewModel.nextTick = utils.nextTick

/**
* Expose the main ViewModel class
Expand Down
12 changes: 10 additions & 2 deletions src/viewmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ def(VMProto, '$set', function (key, value) {
* fire callback with new value
*/
def(VMProto, '$watch', function (key, callback) {
this.$compiler.observer.on('change:' + key, callback)
var self = this
function on () {
var args = arguments
utils.nextTick(function () {
callback.apply(self, args)
})
}
callback._fn = on
self.$compiler.observer.on('change:' + key, on)
})

/**
Expand All @@ -49,7 +57,7 @@ def(VMProto, '$unwatch', function (key, callback) {
// by checking the length of arguments
var args = ['change:' + key],
ob = this.$compiler.observer
if (callback) args.push(callback)
if (callback) args.push(callback._fn)
ob.off.apply(ob, args)
})

Expand Down
16 changes: 10 additions & 6 deletions test/functional/specs/todomvc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ casper.test.begin('todomvc', 69, function (test) {
// let's add a new item -----------------------------------------------

.then(function () {
createNewItem('test')
casper.sendKeys('#new-todo', 'test')
})
.then(function () {
// wait before hitting enter
// so v-model unlocks
createNewItem()
})
.then(function () {

Expand All @@ -31,10 +36,7 @@ casper.test.begin('todomvc', 69, function (test) {
test.assertVisible('#main', '#main should now be visible')
test.assertVisible('#footer', '#footer should now be visible')
test.assertNotVisible('#clear-completed', '#clear-completed should be hidden')

test.assertEvalEquals(function () {
return __utils__.findOne('#new-todo').value
}, '', 'new todo input should be reset')
test.assertField({type:'css',path:'#new-todo'}, '', 'new todo input should be reset')

})

Expand Down Expand Up @@ -256,7 +258,9 @@ casper.test.begin('todomvc', 69, function (test) {
// helper ===============

function createNewItem (text) {
casper.sendKeys('#new-todo', text)
if (text) {
casper.sendKeys('#new-todo', text)
}
casper.evaluate(function () {
// casper.mouseEvent can't set keyCode
var field = document.getElementById('new-todo'),
Expand Down
7 changes: 5 additions & 2 deletions test/unit/specs/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('Misc Features', function () {
})

describe('setting an object to empty', function () {
it('should emit undefined for paths in the old object', function () {
it('should emit undefined for paths in the old object', function (done) {
var v = new Vue({
data: {
a: {
Expand All @@ -59,7 +59,10 @@ describe('Misc Features', function () {
emitted = true
})
v.a = {}
assert.ok(emitted)
nextTick(function () {
assert.ok(emitted)
done()
})
})
})

Expand Down
55 changes: 39 additions & 16 deletions test/unit/specs/viewmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,19 @@ describe('UNIT: ViewModel', function () {

describe('.$watch()', function () {

it('should trigger callback when a plain value changes', function () {
it('should trigger callback when a plain value changes', function (done) {
var val
vm.$watch('a.b.c', function (newVal) {
val = newVal
})
data.b.c = 'new value!'
assert.strictEqual(val, data.b.c)
nextTick(function () {
assert.strictEqual(val, data.b.c)
done()
})
})

it('should trigger callback when an object value changes', function () {
it('should trigger callback when an object value changes', function (done) {
var val, subVal, rootVal,
target = { c: 'hohoho' }
vm.$watch('a.b', function (newVal) {
Expand All @@ -47,31 +50,45 @@ describe('UNIT: ViewModel', function () {
vm.$watch('a', function (newVal) {
rootVal = newVal
})

data.b = target
assert.strictEqual(val, target)
assert.strictEqual(subVal, target.c)
vm.a = 'hehehe'
assert.strictEqual(rootVal, 'hehehe')
nextTick(function () {
assert.strictEqual(val, target)
assert.strictEqual(subVal, target.c)
next()
})

function next () {
vm.a = 'hehehe'
nextTick(function () {
assert.strictEqual(rootVal, 'hehehe')
done()
})
}

})

it('should trigger callback when an array mutates', function () {
it('should trigger callback when an array mutates', function (done) {
var val, mut
vm.$watch('b', function (array, mutation) {
val = array
mut = mutation
})
arr.push(4)
assert.strictEqual(val, arr)
assert.strictEqual(mut.method, 'push')
assert.strictEqual(mut.args.length, 1)
assert.strictEqual(mut.args[0], 4)
nextTick(function () {
assert.strictEqual(val, arr)
assert.strictEqual(mut.method, 'push')
assert.strictEqual(mut.args.length, 1)
assert.strictEqual(mut.args[0], 4)
done()
})
})

})

describe('.$unwatch()', function () {

it('should unwatch the stuff', function () {
it('should unwatch the stuff', function (done) {
var triggered = false
vm.$watch('a.b.c', function () {
triggered = true
Expand All @@ -87,7 +104,10 @@ describe('UNIT: ViewModel', function () {
vm.$unwatch('a.b.c')
vm.a = { b: { c:123123 }}
vm.b.push(5)
assert.notOk(triggered)
nextTick(function () {
assert.notOk(triggered)
done()
})
})

})
Expand Down Expand Up @@ -477,7 +497,7 @@ describe('UNIT: ViewModel', function () {
assert.strictEqual(vm.$data, data)
})

it('should be able to be swapped', function () {
it('should be able to be swapped', function (done) {
var data1 = { a: 1 },
data2 = { a: 2 },
vm = new Vue({data: data1}),
Expand All @@ -488,7 +508,10 @@ describe('UNIT: ViewModel', function () {
})
vm.$data = data2
assert.equal(vm.a, 2)
assert.ok(emittedChange)
nextTick(function () {
assert.ok(emittedChange)
done()
})
})
})

Expand Down

0 comments on commit c71a908

Please sign in to comment.