diff --git a/modules/angular2/src/router/route_registry.ts b/modules/angular2/src/router/route_registry.ts index ed9f639938..22eaeb5d21 100644 --- a/modules/angular2/src/router/route_registry.ts +++ b/modules/angular2/src/router/route_registry.ts @@ -249,9 +249,9 @@ export class RouteRegistry { } lastInstructionIsTerminal = lastInstruction.component.terminal; } - if (!lastInstructionIsTerminal) { + if (isPresent(componentCursor) && !lastInstructionIsTerminal) { throw new BaseException( - `Link "${ListWrapper.toJSON(linkParams)}" does not resolve to a terminal instruction.`); + `Link "${ListWrapper.toJSON(linkParams)}" does not resolve to a terminal or async instruction.`); } } diff --git a/modules/angular2/src/router/router.ts b/modules/angular2/src/router/router.ts index 68efc51a4c..4abba0c9f1 100644 --- a/modules/angular2/src/router/router.ts +++ b/modules/angular2/src/router/router.ts @@ -217,7 +217,8 @@ export class Router { _settleInstruction(instruction: Instruction): Promise { var unsettledInstructions: Array> = []; if (isBlank(instruction.component.componentType)) { - unsettledInstructions.push(instruction.component.resolveComponentType()); + unsettledInstructions.push(instruction.component.resolveComponentType().then( + (type: Type) => { this.registry.configFromComponent(type); })); } if (isPresent(instruction.child)) { unsettledInstructions.push(this._settleInstruction(instruction.child)); diff --git a/modules/angular2/test/router/integration/router_link_spec.ts b/modules/angular2/test/router/integration/router_link_spec.ts index f0353e14d2..e997065d95 100644 --- a/modules/angular2/test/router/integration/router_link_spec.ts +++ b/modules/angular2/test/router/integration/router_link_spec.ts @@ -17,6 +17,7 @@ import { } from 'angular2/test_lib'; import {NumberWrapper} from 'angular2/src/core/facade/lang'; +import {PromiseWrapper} from 'angular2/src/core/facade/async'; import {bind, Component, DirectiveResolver, View} from 'angular2/core'; @@ -29,6 +30,7 @@ import { Pipeline, RouterLink, RouterOutlet, + AsyncRoute, Route, RouteParams, RouteConfig, @@ -96,7 +98,6 @@ export function main() { })); - it('should generate link hrefs with params', inject([AsyncTestCompleter], (async) => { compile('{{name}}') .then((_) => router.config( @@ -128,6 +129,31 @@ export function main() { }); })); + it('should generate link hrefs when asynchronously loaded', + inject([AsyncTestCompleter], (async) => { + compile() + .then((_) => router.config([ + new AsyncRoute({ + path: '/child-with-grandchild/...', + loader: parentCmpLoader, + as: 'child-with-grandchild' + }) + ])) + .then((_) => { + // TODO: refactor when https://github.com/angular/angular/pull/4074 lands + var instruction = router.generate(['/child-with-grandchild']); + return router.navigateInstruction(instruction); + }) + .then((_) => { + rootTC.detectChanges(); + expect(DOM.getAttribute( + rootTC.componentViewChildren[1].componentViewChildren[0].nativeElement, + 'href')) + .toEqual('/child-with-grandchild/grandchild'); + async.done(); + }); + })); + it('should generate relative links preserving the existing parent route', inject([AsyncTestCompleter], (async) => { compile() @@ -319,6 +345,10 @@ class HelloCmp { class Hello2Cmp { } +function parentCmpLoader() { + return PromiseWrapper.resolve(ParentCmp); +} + @Component({selector: 'parent-cmp'}) @View({ template: `{ Grandchild diff --git a/modules/angular2/test/router/route_registry_spec.ts b/modules/angular2/test/router/route_registry_spec.ts index 4ee6271a60..0d20d75c59 100644 --- a/modules/angular2/test/router/route_registry_spec.ts +++ b/modules/angular2/test/router/route_registry_spec.ts @@ -235,7 +235,7 @@ export function main() { registry.config(RootHostCmp, new Route({path: '/first/...', component: DummyParentCmp, as: 'first'})); expect(() => { registry.generate(['first'], RootHostCmp); }) - .toThrowError('Link "["first"]" does not resolve to a terminal instruction.'); + .toThrowError('Link "["first"]" does not resolve to a terminal or async instruction.'); }); it('should match matrix params on child components and query params on the root component',