Skip to content

Commit c71a908

Browse files
committed
Async fixes
- vm.$watch is now async - v-model now unlocks async (so it is properly locked during async update) - expose Vue.nextTick
1 parent 6cbb9fa commit c71a908

File tree

6 files changed

+68
-27
lines changed

6 files changed

+68
-27
lines changed

src/directives/model.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ module.exports = {
5353
// no filters, don't let it trigger update()
5454
self.lock = true
5555
self.vm.$set(self.key, el[attr])
56-
self.lock = false
56+
utils.nextTick(function () {
57+
self.lock = false
58+
})
5759
}
5860
el.addEventListener(self.event, self.set)
5961

src/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ ViewModel.transition = function (id, transition) {
6666
}
6767

6868
ViewModel.extend = extend
69+
ViewModel.nextTick = utils.nextTick
6970

7071
/**
7172
* Expose the main ViewModel class

src/viewmodel.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,15 @@ def(VMProto, '$set', function (key, value) {
3737
* fire callback with new value
3838
*/
3939
def(VMProto, '$watch', function (key, callback) {
40-
this.$compiler.observer.on('change:' + key, callback)
40+
var self = this
41+
function on () {
42+
var args = arguments
43+
utils.nextTick(function () {
44+
callback.apply(self, args)
45+
})
46+
}
47+
callback._fn = on
48+
self.$compiler.observer.on('change:' + key, on)
4149
})
4250

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

test/functional/specs/todomvc.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ casper.test.begin('todomvc', 69, function (test) {
1616
// let's add a new item -----------------------------------------------
1717

1818
.then(function () {
19-
createNewItem('test')
19+
casper.sendKeys('#new-todo', 'test')
20+
})
21+
.then(function () {
22+
// wait before hitting enter
23+
// so v-model unlocks
24+
createNewItem()
2025
})
2126
.then(function () {
2227

@@ -31,10 +36,7 @@ casper.test.begin('todomvc', 69, function (test) {
3136
test.assertVisible('#main', '#main should now be visible')
3237
test.assertVisible('#footer', '#footer should now be visible')
3338
test.assertNotVisible('#clear-completed', '#clear-completed should be hidden')
34-
35-
test.assertEvalEquals(function () {
36-
return __utils__.findOne('#new-todo').value
37-
}, '', 'new todo input should be reset')
39+
test.assertField({type:'css',path:'#new-todo'}, '', 'new todo input should be reset')
3840

3941
})
4042

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

258260
function createNewItem (text) {
259-
casper.sendKeys('#new-todo', text)
261+
if (text) {
262+
casper.sendKeys('#new-todo', text)
263+
}
260264
casper.evaluate(function () {
261265
// casper.mouseEvent can't set keyCode
262266
var field = document.getElementById('new-todo'),

test/unit/specs/misc.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('Misc Features', function () {
4545
})
4646

4747
describe('setting an object to empty', function () {
48-
it('should emit undefined for paths in the old object', function () {
48+
it('should emit undefined for paths in the old object', function (done) {
4949
var v = new Vue({
5050
data: {
5151
a: {
@@ -59,7 +59,10 @@ describe('Misc Features', function () {
5959
emitted = true
6060
})
6161
v.a = {}
62-
assert.ok(emitted)
62+
nextTick(function () {
63+
assert.ok(emitted)
64+
done()
65+
})
6366
})
6467
})
6568

test/unit/specs/viewmodel.js

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,19 @@ describe('UNIT: ViewModel', function () {
2626

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

29-
it('should trigger callback when a plain value changes', function () {
29+
it('should trigger callback when a plain value changes', function (done) {
3030
var val
3131
vm.$watch('a.b.c', function (newVal) {
3232
val = newVal
3333
})
3434
data.b.c = 'new value!'
35-
assert.strictEqual(val, data.b.c)
35+
nextTick(function () {
36+
assert.strictEqual(val, data.b.c)
37+
done()
38+
})
3639
})
3740

38-
it('should trigger callback when an object value changes', function () {
41+
it('should trigger callback when an object value changes', function (done) {
3942
var val, subVal, rootVal,
4043
target = { c: 'hohoho' }
4144
vm.$watch('a.b', function (newVal) {
@@ -47,31 +50,45 @@ describe('UNIT: ViewModel', function () {
4750
vm.$watch('a', function (newVal) {
4851
rootVal = newVal
4952
})
53+
5054
data.b = target
51-
assert.strictEqual(val, target)
52-
assert.strictEqual(subVal, target.c)
53-
vm.a = 'hehehe'
54-
assert.strictEqual(rootVal, 'hehehe')
55+
nextTick(function () {
56+
assert.strictEqual(val, target)
57+
assert.strictEqual(subVal, target.c)
58+
next()
59+
})
60+
61+
function next () {
62+
vm.a = 'hehehe'
63+
nextTick(function () {
64+
assert.strictEqual(rootVal, 'hehehe')
65+
done()
66+
})
67+
}
68+
5569
})
5670

57-
it('should trigger callback when an array mutates', function () {
71+
it('should trigger callback when an array mutates', function (done) {
5872
var val, mut
5973
vm.$watch('b', function (array, mutation) {
6074
val = array
6175
mut = mutation
6276
})
6377
arr.push(4)
64-
assert.strictEqual(val, arr)
65-
assert.strictEqual(mut.method, 'push')
66-
assert.strictEqual(mut.args.length, 1)
67-
assert.strictEqual(mut.args[0], 4)
78+
nextTick(function () {
79+
assert.strictEqual(val, arr)
80+
assert.strictEqual(mut.method, 'push')
81+
assert.strictEqual(mut.args.length, 1)
82+
assert.strictEqual(mut.args[0], 4)
83+
done()
84+
})
6885
})
6986

7087
})
7188

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

74-
it('should unwatch the stuff', function () {
91+
it('should unwatch the stuff', function (done) {
7592
var triggered = false
7693
vm.$watch('a.b.c', function () {
7794
triggered = true
@@ -87,7 +104,10 @@ describe('UNIT: ViewModel', function () {
87104
vm.$unwatch('a.b.c')
88105
vm.a = { b: { c:123123 }}
89106
vm.b.push(5)
90-
assert.notOk(triggered)
107+
nextTick(function () {
108+
assert.notOk(triggered)
109+
done()
110+
})
91111
})
92112

93113
})
@@ -477,7 +497,7 @@ describe('UNIT: ViewModel', function () {
477497
assert.strictEqual(vm.$data, data)
478498
})
479499

480-
it('should be able to be swapped', function () {
500+
it('should be able to be swapped', function (done) {
481501
var data1 = { a: 1 },
482502
data2 = { a: 2 },
483503
vm = new Vue({data: data1}),
@@ -488,7 +508,10 @@ describe('UNIT: ViewModel', function () {
488508
})
489509
vm.$data = data2
490510
assert.equal(vm.a, 2)
491-
assert.ok(emittedChange)
511+
nextTick(function () {
512+
assert.ok(emittedChange)
513+
done()
514+
})
492515
})
493516
})
494517

0 commit comments

Comments
 (0)