X Tutup
Skip to content

Commit 26d2ea8

Browse files
committed
fix(router): fix regression with generating links to async routes
Closes #3650
1 parent 2686316 commit 26d2ea8

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

modules/angular2/src/router/router.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Promise, PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
2-
import {Map, MapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
2+
import {Map, StringMapWrapper, MapWrapper, List, ListWrapper} from 'angular2/src/facade/collection';
33
import {
44
isBlank,
55
isString,
@@ -131,7 +131,8 @@ export class Router {
131131
}
132132

133133
_navigate(instruction: Instruction, _skipLocationChange: boolean): Promise<any> {
134-
return this._reuse(instruction)
134+
return this._settleInstruction(instruction)
135+
.then((_) => this._reuse(instruction))
135136
.then((_) => this._canActivate(instruction))
136137
.then((result) => {
137138
if (!result) {
@@ -150,6 +151,25 @@ export class Router {
150151
});
151152
}
152153

154+
// TODO(btford): it'd be nice to remove this method as part of cleaning up the traversal logic
155+
// Since refactoring `Router.generate` to return an instruction rather than a string, it's not
156+
// guaranteed that the `componentType`s for the terminal async routes have been loaded by the time
157+
// we begin navigation. The method below simply traverses instructions and resolves any components
158+
// for which `componentType` is not present
159+
_settleInstruction(instruction: Instruction): Promise<any> {
160+
var unsettledInstructions: List<Promise<any>> = [];
161+
if (isBlank(instruction.component.componentType)) {
162+
unsettledInstructions.push(instruction.component.resolveComponentType());
163+
}
164+
if (isPresent(instruction.child)) {
165+
unsettledInstructions.push(this._settleInstruction(instruction.child));
166+
}
167+
StringMapWrapper.forEach(instruction.auxInstruction, (instruction, _) => {
168+
unsettledInstructions.push(this._settleInstruction(instruction));
169+
});
170+
return PromiseWrapper.all(unsettledInstructions);
171+
}
172+
153173
private _emitNavigationFinish(url): void { ObservableWrapper.callNext(this._subject, url); }
154174

155175
private _afterPromiseFinishNavigating(promise: Promise<any>): Promise<any> {

modules/angular2/test/router/router_spec.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import {
1111
beforeEachBindings,
1212
SpyObject
1313
} from 'angular2/test_lib';
14-
import {IMPLEMENTS} from 'angular2/src/facade/lang';
15-
14+
import {IMPLEMENTS, Type} from 'angular2/src/facade/lang';
1615
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
1716
import {ListWrapper} from 'angular2/src/facade/collection';
17+
1818
import {Router, RootRouter} from 'angular2/src/router/router';
1919
import {Pipeline} from 'angular2/src/router/pipeline';
2020
import {RouterOutlet} from 'angular2/src/router/router_outlet';
@@ -23,7 +23,7 @@ import {Location} from 'angular2/src/router/location';
2323
import {stringifyInstruction} from 'angular2/src/router/instruction';
2424

2525
import {RouteRegistry} from 'angular2/src/router/route_registry';
26-
import {RouteConfig, Route} from 'angular2/src/router/route_config_decorator';
26+
import {RouteConfig, AsyncRoute, Route} from 'angular2/src/router/route_config_decorator';
2727
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
2828

2929
import {bind} from 'angular2/di';
@@ -133,6 +133,21 @@ export function main() {
133133
expect(stringifyInstruction(instruction)).toEqual('first/second');
134134
});
135135

136+
it('should generate an instruction with terminal async routes',
137+
inject([AsyncTestCompleter], (async) => {
138+
var outlet = makeDummyOutlet();
139+
140+
router.registerOutlet(outlet);
141+
router.config([new AsyncRoute({path: '/first', loader: loader, as: 'FirstCmp'})]);
142+
143+
var instruction = router.generate(['/FirstCmp']);
144+
router.navigateInstruction(instruction)
145+
.then((_) => {
146+
expect(outlet.spy('commit')).toHaveBeenCalled();
147+
async.done();
148+
});
149+
}));
150+
136151
describe('query string params', () => {
137152
it('should use query string params for the root route', () => {
138153
router.config(
@@ -178,6 +193,10 @@ export function main() {
178193
});
179194
}
180195

196+
function loader(): Promise<Type> {
197+
return PromiseWrapper.resolve(DummyComponent);
198+
}
199+
181200
@proxy
182201
@IMPLEMENTS(RouterOutlet)
183202
class DummyOutlet extends SpyObject {

0 commit comments

Comments
 (0)
X Tutup