Skip to content

Commit 33eae50

Browse files
committed
implement router.onReady
1 parent f5e9fcf commit 33eae50

File tree

5 files changed

+173
-104
lines changed

5 files changed

+173
-104
lines changed

src/history/base.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export class History {
1313
current: Route;
1414
pending: ?Route;
1515
cb: (r: Route) => void;
16+
ready: boolean;
17+
readyCbs: Array<Function>;
1618

1719
// implemented by sub-classes
1820
go: (n: number) => void;
@@ -27,18 +29,36 @@ export class History {
2729
// start with a route object that stands for "nowhere"
2830
this.current = START
2931
this.pending = null
32+
this.ready = false
33+
this.readyCbs = []
3034
}
3135

3236
listen (cb: Function) {
3337
this.cb = cb
3438
}
3539

40+
onReady (cb: Function) {
41+
if (this.ready) {
42+
cb()
43+
} else {
44+
this.readyCbs.push(cb)
45+
}
46+
}
47+
3648
transitionTo (location: RawLocation, onComplete?: Function, onAbort?: Function) {
3749
const route = this.router.match(location, this.current)
3850
this.confirmTransition(route, () => {
3951
this.updateRoute(route)
4052
onComplete && onComplete(route)
4153
this.ensureURL()
54+
55+
// fire ready cbs once
56+
if (!this.ready) {
57+
this.ready = true
58+
this.readyCbs.forEach(cb => {
59+
cb(route)
60+
})
61+
}
4262
}, onAbort)
4363
}
4464

src/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export default class VueRouter {
1919

2020
app: any;
2121
apps: Array<any>;
22+
ready: boolean;
23+
readyCbs: Array<Function>;
2224
options: RouterOptions;
2325
mode: string;
2426
history: HashHistory | HTML5History | AbstractHistory;
@@ -112,6 +114,10 @@ export default class VueRouter {
112114
this.afterHooks.push(fn)
113115
}
114116

117+
onReady (cb: Function) {
118+
this.history.onReady(cb)
119+
}
120+
115121
push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
116122
this.history.push(location, onComplete, onAbort)
117123
}

test/unit/specs/add-routes.spec.js

Lines changed: 0 additions & 34 deletions
This file was deleted.

test/unit/specs/api.spec.js

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import Router from '../../../src/index'
2+
3+
describe('router.onReady', () => {
4+
it('should work', done => {
5+
const calls = []
6+
7+
const router = new Router({
8+
mode: 'abstract',
9+
routes: [
10+
{
11+
path: '/a',
12+
component: {
13+
name: 'A',
14+
beforeRouteEnter: (to, from, next) => {
15+
setTimeout(() => {
16+
calls.push(2)
17+
next()
18+
}, 1)
19+
}
20+
}
21+
}
22+
]
23+
})
24+
25+
router.beforeEach((to, from, next) => {
26+
setTimeout(() => {
27+
calls.push(1)
28+
next()
29+
}, 1)
30+
})
31+
32+
router.onReady(() => {
33+
expect(calls).toEqual([1, 2])
34+
// sync call when already ready
35+
router.onReady(() => {
36+
calls.push(3)
37+
})
38+
expect(calls).toEqual([1, 2, 3])
39+
done()
40+
})
41+
42+
router.push('/a')
43+
expect(calls).toEqual([])
44+
})
45+
})
46+
47+
describe('router.addRoutes', () => {
48+
it('should work', () => {
49+
const router = new Router({
50+
mode: 'abstract',
51+
routes: [
52+
{ path: '/a', component: { name: 'A' }}
53+
]
54+
})
55+
56+
router.push('/a')
57+
let components = router.getMatchedComponents()
58+
expect(components.length).toBe(1)
59+
expect(components[0].name).toBe('A')
60+
61+
router.push('/b')
62+
components = router.getMatchedComponents()
63+
expect(components.length).toBe(0)
64+
65+
router.addRoutes([
66+
{ path: '/b', component: { name: 'B' }}
67+
])
68+
components = router.getMatchedComponents()
69+
expect(components.length).toBe(1)
70+
expect(components[0].name).toBe('B')
71+
72+
// make sure it preserves previous routes
73+
router.push('/a')
74+
components = router.getMatchedComponents()
75+
expect(components.length).toBe(1)
76+
expect(components[0].name).toBe('A')
77+
})
78+
})
79+
80+
describe('router.push/replace callbacks', () => {
81+
let calls = []
82+
let router, spy1, spy2
83+
84+
const Foo = {
85+
beforeRouteEnter (to, from, next) {
86+
calls.push(3)
87+
setTimeout(() => {
88+
calls.push(4)
89+
next()
90+
}, 1)
91+
}
92+
}
93+
94+
beforeEach(() => {
95+
calls = []
96+
spy1 = jasmine.createSpy('complete')
97+
spy2 = jasmine.createSpy('abort')
98+
99+
router = new Router({
100+
routes: [
101+
{ path: '/foo', component: Foo }
102+
]
103+
})
104+
105+
router.beforeEach((to, from, next) => {
106+
calls.push(1)
107+
setTimeout(() => {
108+
calls.push(2)
109+
next()
110+
}, 1)
111+
})
112+
})
113+
114+
it('push complete', done => {
115+
router.push('/foo', () => {
116+
expect(calls).toEqual([1, 2, 3, 4])
117+
done()
118+
})
119+
})
120+
121+
it('push abort', done => {
122+
router.push('/foo', spy1, spy2)
123+
router.push('/bar', () => {
124+
expect(calls).toEqual([1, 1, 2, 2])
125+
expect(spy1).not.toHaveBeenCalled()
126+
expect(spy2).toHaveBeenCalled()
127+
done()
128+
})
129+
})
130+
131+
it('replace complete', done => {
132+
router.replace('/foo', () => {
133+
expect(calls).toEqual([1, 2, 3, 4])
134+
done()
135+
})
136+
})
137+
138+
it('replace abort', done => {
139+
router.replace('/foo', spy1, spy2)
140+
router.replace('/bar', () => {
141+
expect(calls).toEqual([1, 1, 2, 2])
142+
expect(spy1).not.toHaveBeenCalled()
143+
expect(spy2).toHaveBeenCalled()
144+
done()
145+
})
146+
})
147+
})

test/unit/specs/navigation-callback.spec.js

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)