| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal'; | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | 
					
						
							|  |  |  | import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing'; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {Location} from '@angular/common'; | 
					
						
							|  |  |  | import {NumberWrapper} from '../../src/facade/lang'; | 
					
						
							|  |  |  | import {PromiseWrapper} from '../../src/facade/async'; | 
					
						
							|  |  |  | import {ListWrapper} from '../../src/facade/collection'; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {provide, Component} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {Router, RouteRegistry, RouterLink, RouterOutlet, AsyncRoute, AuxRoute, Route, RouteParams, RouteConfig, ROUTER_DIRECTIVES, ROUTER_PRIMARY_COMPONENT} from '@angular/router-deprecated'; | 
					
						
							| 
									
										
										
										
											2016-05-02 10:36:58 -07:00
										 |  |  | import {RootRouter} from '@angular/router-deprecated/src/router'; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; | 
					
						
							|  |  |  | import {By} from '@angular/platform-browser/src/dom/debug/by'; | 
					
						
							|  |  |  | import {SpyLocation} from '@angular/common/testing'; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |   describe('routerLink directive', function() { | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |     var tcb: TestComponentBuilder; | 
					
						
							| 
									
										
										
										
											2016-04-30 10:52:04 -07:00
										 |  |  |     var fixture: ComponentFixture<any>; | 
					
						
							| 
									
										
										
										
											2016-02-19 11:49:31 -08:00
										 |  |  |     var router: Router; | 
					
						
							|  |  |  |     var location: Location; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     beforeEachProviders( | 
					
						
							|  |  |  |         () => | 
					
						
							|  |  |  |             [RouteRegistry, {provide: Location, useClass: SpyLocation}, | 
					
						
							|  |  |  |              {provide: ROUTER_PRIMARY_COMPONENT, useValue: MyComp7}, | 
					
						
							|  |  |  |              {provide: Router, useClass: RootRouter}, | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     beforeEach(inject( | 
					
						
							|  |  |  |         [TestComponentBuilder, Router, Location], | 
					
						
							|  |  |  |         (tcBuilder: any /** TODO #9100 */, rtr: Router, loc: Location) => { | 
					
						
							|  |  |  |           tcb = tcBuilder; | 
					
						
							|  |  |  |           router = rtr; | 
					
						
							|  |  |  |           location = loc; | 
					
						
							|  |  |  |         })); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     function compile(template: string = '<router-outlet></router-outlet>') { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |       return tcb.overrideTemplate(MyComp7, ('<div>' + template + '</div>')) | 
					
						
							|  |  |  |           .createAsync(MyComp7) | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |           .then((tc) => { fixture = tc; }); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should generate absolute hrefs that include the base href', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2016-02-19 11:49:31 -08:00
										 |  |  |          (<SpyLocation>location).setBaseHref('/my/base'); | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |          compile('<a href="hello" [routerLink]="[\'./User\']"></a>') | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then( | 
					
						
							|  |  |  |                  (_) => | 
					
						
							|  |  |  |                      router.config([new Route({path: '/user', component: UserCmp, name: 'User'})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => router.navigateByUrl('/a/b')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(getHref(fixture)).toEqual('/my/base/user'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should generate link hrefs without params', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |          compile('<a href="hello" [routerLink]="[\'./User\']"></a>') | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then( | 
					
						
							|  |  |  |                  (_) => | 
					
						
							|  |  |  |                      router.config([new Route({path: '/user', component: UserCmp, name: 'User'})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => router.navigateByUrl('/a/b')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(getHref(fixture)).toEqual('/user'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should generate link hrefs with params', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |          compile('<a href="hello" [routerLink]="[\'./User\', {name: name}]">{{name}}</a>') | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => router.config([new Route( | 
					
						
							|  |  |  |                        {path: '/user/:name', component: UserCmp, name: 'User'})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => router.navigateByUrl('/a/b')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.debugElement.componentInstance.name = 'brian'; | 
					
						
							|  |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('brian'); | 
					
						
							| 
									
										
										
										
											2016-01-13 21:35:21 -08:00
										 |  |  |                expect(getHref(fixture)).toEqual('/user/brian'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should generate link hrefs from a child to its sibling', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |          compile() | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => router.config([new Route( | 
					
						
							|  |  |  |                        {path: '/page/:number', component: SiblingPageCmp, name: 'Page'})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => router.navigateByUrl('/page/1')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-01-13 21:35:21 -08:00
										 |  |  |                expect(getHref(fixture)).toEqual('/page/2'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |     it('should generate link hrefs from a child to its sibling with no leading slash', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |          compile() | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => router.config([new Route( | 
					
						
							|  |  |  |                        {path: '/page/:number', component: NoPrefixSiblingPageCmp, name: 'Page'})])) | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |              .then((_) => router.navigateByUrl('/page/1')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-01-13 21:35:21 -08:00
										 |  |  |                expect(getHref(fixture)).toEqual('/page/2'); | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should generate link hrefs to a child with no leading slash', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |          compile() | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => router.config([new Route( | 
					
						
							|  |  |  |                        {path: '/book/:title/...', component: NoPrefixBookCmp, name: 'Book'})])) | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |              .then((_) => router.navigateByUrl('/book/1984/page/1')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-01-13 21:35:21 -08:00
										 |  |  |                expect(getHref(fixture)).toEqual('/book/1984/page/100'); | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw when links without a leading slash are ambiguous', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |          compile() | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => router.config([new Route( | 
					
						
							|  |  |  |                        {path: '/book/:title/...', component: AmbiguousBookCmp, name: 'Book'})])) | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |              .then((_) => router.navigateByUrl('/book/1984/page/1')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                var link = ListWrapper.toJSON(['Book', {number: 100}]); | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                expect(() => fixture.detectChanges()) | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |                    .toThrowErrorWith( | 
					
						
							|  |  |  |                        `Link "${link}" is ambiguous, use "./" or "../" to disambiguate.`); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 14:50:41 -07:00
										 |  |  |     it('should generate link hrefs when asynchronously loaded', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-09-11 14:50:41 -07:00
										 |  |  |          compile() | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => router.config([new AsyncRoute({ | 
					
						
							|  |  |  |                path: '/child-with-grandchild/...', | 
					
						
							|  |  |  |                loader: parentCmpLoader, | 
					
						
							|  |  |  |                name: 'ChildWithGrandchild' | 
					
						
							|  |  |  |              })])) | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:10 -08:00
										 |  |  |              .then((_) => router.navigateByUrl('/child-with-grandchild/grandchild')) | 
					
						
							| 
									
										
										
										
											2015-09-11 14:50:41 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-01-13 21:35:21 -08:00
										 |  |  |                expect(getHref(fixture)).toEqual('/child-with-grandchild/grandchild'); | 
					
						
							| 
									
										
										
										
											2015-09-11 14:50:41 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |     it('should generate relative links preserving the existing parent route', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |          compile() | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => router.config([new Route( | 
					
						
							|  |  |  |                        {path: '/book/:title/...', component: BookCmp, name: 'Book'})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => router.navigateByUrl('/book/1984/page/1')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-01-13 21:35:21 -08:00
										 |  |  |                // TODO(juliemr): This should be one By.css('book-cmp a') query, but the parse5
 | 
					
						
							|  |  |  |                // adapter
 | 
					
						
							|  |  |  |                // can't handle css child selectors.
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                expect(getDOM().getAttribute( | 
					
						
							|  |  |  |                           fixture.debugElement.query(By.css('book-cmp')) | 
					
						
							|  |  |  |                               .query(By.css('a')) | 
					
						
							|  |  |  |                               .nativeElement, | 
					
						
							|  |  |  |                           'href')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                    .toEqual('/book/1984/page/100'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                expect(getDOM().getAttribute( | 
					
						
							|  |  |  |                           fixture.debugElement.query(By.css('page-cmp')) | 
					
						
							|  |  |  |                               .query(By.css('a')) | 
					
						
							|  |  |  |                               .nativeElement, | 
					
						
							|  |  |  |                           'href')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                    .toEqual('/book/1984/page/2'); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should generate links to auxiliary routes', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:10 -08:00
										 |  |  |          compile() | 
					
						
							|  |  |  |              .then((_) => router.config([new Route({path: '/...', component: AuxLinkCmp})])) | 
					
						
							|  |  |  |              .then((_) => router.navigateByUrl('/')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
											  
											
												refactor(router): improve recognition and generation pipeline
This is a big change. @matsko also deserves much of the credit for the implementation.
Previously, `ComponentInstruction`s held all the state for async components.
Now, we introduce several subclasses for `Instruction` to describe each type of navigation.
BREAKING CHANGE:
Redirects now use the Link DSL syntax. Before:
```
@RouteConfig([
	{ path: '/foo', redirectTo: '/bar' },
	{ path: '/bar', component: BarCmp }
])
```
After:
```
@RouteConfig([
	{ path: '/foo', redirectTo: ['Bar'] },
	{ path: '/bar', component: BarCmp, name: 'Bar' }
])
```
BREAKING CHANGE:
This also introduces `useAsDefault` in the RouteConfig, which makes cases like lazy-loading
and encapsulating large routes with sub-routes easier.
Previously, you could use `redirectTo` like this to expand a URL like `/tab` to `/tab/posts`:
@RouteConfig([
	{ path: '/tab', redirectTo: '/tab/users' }
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
Now the recommended way to handle this is case is to use `useAsDefault` like so:
```
@RouteConfig([
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
@RouteConfig([
	{ path: '/posts', component: PostsCmp, useAsDefault: true, name: 'Posts' },
	{ path: '/users', component: UsersCmp, name: 'Users' }
])
TabsCmp { ... }
```
In the above example, you can write just `['/Tab']` and the route `Users` is automatically selected as a child route.
Closes #4728
Closes #4228
Closes #4170
Closes #4490
Closes #4694
Closes #5200
Closes #5475
											
										 
											2015-11-23 18:07:37 -08:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-01-13 21:35:21 -08:00
										 |  |  |                expect(getHref(fixture)).toEqual('/(aside)'); | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:10 -08:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  |     describe('router-link-active CSS class', () => { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       it('should be added to the associated element', | 
					
						
							|  |  |  |          inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							|  |  |  |            router | 
					
						
							|  |  |  |                .config([ | 
					
						
							|  |  |  |                  new Route({path: '/child', component: HelloCmp, name: 'Child'}), | 
					
						
							|  |  |  |                  new Route({path: '/better-child', component: Hello2Cmp, name: 'BetterChild'}) | 
					
						
							|  |  |  |                ]) | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |                .then((_) => compile(`<a [routerLink]="['./Child']" class="child-link">Child</a>
 | 
					
						
							|  |  |  |                                 <a [routerLink]="['./BetterChild']" class="better-child-link">Better Child</a> | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  |                                 <router-outlet></router-outlet>`)) | 
					
						
							|  |  |  |                .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                  var element = fixture.debugElement.nativeElement; | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                  fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |                  var link1 = getDOM().querySelector(element, '.child-link'); | 
					
						
							|  |  |  |                  var link2 = getDOM().querySelector(element, '.better-child-link'); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                  expect(link1).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                  expect(link2).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  router.subscribe((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                    fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                    expect(link1).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                    expect(link2).toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							| 
									
										
										
										
											2016-03-30 11:26:31 -07:00
										 |  |  |                  router.navigateByUrl('/better-child?extra=0'); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  |                }); | 
					
						
							|  |  |  |          })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       it('should be added to links in child routes', | 
					
						
							|  |  |  |          inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							|  |  |  |            router | 
					
						
							|  |  |  |                .config([ | 
					
						
							|  |  |  |                  new Route({path: '/child', component: HelloCmp, name: 'Child'}), new Route({ | 
					
						
							|  |  |  |                    path: '/child-with-grandchild/...', | 
					
						
							|  |  |  |                    component: ParentCmp, | 
					
						
							|  |  |  |                    name: 'ChildWithGrandchild' | 
					
						
							|  |  |  |                  }) | 
					
						
							|  |  |  |                ]) | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |                .then((_) => compile(`<a [routerLink]="['./Child']" class="child-link">Child</a>
 | 
					
						
							|  |  |  |                                 <a [routerLink]="['./ChildWithGrandchild/Grandchild']" class="child-with-grandchild-link">Better Child</a> | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  |                                 <router-outlet></router-outlet>`)) | 
					
						
							|  |  |  |                .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                  var element = fixture.debugElement.nativeElement; | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                  fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |                  var link1 = getDOM().querySelector(element, '.child-link'); | 
					
						
							|  |  |  |                  var link2 = getDOM().querySelector(element, '.child-with-grandchild-link'); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                  expect(link1).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                  expect(link2).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  router.subscribe((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                    fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                    expect(link1).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                    expect(link2).toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |                    var link3 = getDOM().querySelector(element, '.grandchild-link'); | 
					
						
							|  |  |  |                    var link4 = getDOM().querySelector(element, '.better-grandchild-link'); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                    expect(link3).toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                    expect(link4).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							| 
									
										
										
										
											2016-03-30 11:26:31 -07:00
										 |  |  |                  router.navigateByUrl('/child-with-grandchild/grandchild?extra=0'); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  |                }); | 
					
						
							|  |  |  |          })); | 
					
						
							| 
									
										
										
										
											2016-04-22 01:43:59 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should not be added to links in other child routes', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |          inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |            router | 
					
						
							|  |  |  |                .config([ | 
					
						
							|  |  |  |                  new Route({path: '/child', component: HelloCmp, name: 'Child'}), new Route({ | 
					
						
							|  |  |  |                    path: '/child-with-grandchild/...', | 
					
						
							|  |  |  |                    component: ParentCmp, | 
					
						
							|  |  |  |                    name: 'ChildWithGrandchild' | 
					
						
							|  |  |  |                  }), | 
					
						
							|  |  |  |                  new Route({ | 
					
						
							|  |  |  |                    path: '/child-with-other-grandchild/...', | 
					
						
							|  |  |  |                    component: ParentCmp, | 
					
						
							|  |  |  |                    name: 'ChildWithOtherGrandchild' | 
					
						
							|  |  |  |                  }) | 
					
						
							|  |  |  |                ]) | 
					
						
							| 
									
										
										
										
											2016-04-22 01:43:59 +03:00
										 |  |  |                .then((_) => compile(`<a [routerLink]="['./Child']" class="child-link">Child</a>
 | 
					
						
							|  |  |  |                                 <a [routerLink]="['./ChildWithGrandchild/Grandchild']" class="child-with-grandchild-link">Better Child</a> | 
					
						
							|  |  |  |                                 <a [routerLink]="['./ChildWithOtherGrandchild/Grandchild']" class="child-with-other-grandchild-link">Better Child</a> | 
					
						
							|  |  |  |                                 <router-outlet></router-outlet>`)) | 
					
						
							|  |  |  |                .then((_) => { | 
					
						
							|  |  |  |                  var element = fixture.debugElement.nativeElement; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  fixture.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  var link1 = getDOM().querySelector(element, '.child-link'); | 
					
						
							|  |  |  |                  var link2 = getDOM().querySelector(element, '.child-with-grandchild-link'); | 
					
						
							|  |  |  |                  var link3 = getDOM().querySelector(element, '.child-with-other-grandchild-link'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  expect(link1).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                  expect(link2).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                  expect(link3).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  router.subscribe((_) => { | 
					
						
							|  |  |  |                    fixture.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    expect(link1).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                    expect(link2).toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  |                    expect(link3).not.toHaveCssClass('router-link-active'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                  router.navigateByUrl('/child-with-grandchild/grandchild?extra=0'); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |          })); | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |     describe('when clicked', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |       var clickOnElement = function(view: any /** TODO #9100 */) { | 
					
						
							| 
									
										
										
										
											2016-01-13 21:35:21 -08:00
										 |  |  |         var anchorEl = fixture.debugElement.query(By.css('a')).nativeElement; | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |         var dispatchedEvent = getDOM().createMouseEvent('click'); | 
					
						
							|  |  |  |         getDOM().dispatchEvent(anchorEl, dispatchedEvent); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |         return dispatchedEvent; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       it('should navigate to link hrefs without params', | 
					
						
							|  |  |  |          inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |            compile('<a href="hello" [routerLink]="[\'./User\']"></a>') | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                .then((_) => router.config([new Route( | 
					
						
							|  |  |  |                          {path: '/user', component: UserCmp, name: 'User'})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |                .then((_) => router.navigateByUrl('/a/b')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                  fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                  var dispatchedEvent = clickOnElement(fixture); | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |                  expect(getDOM().isPrevented(dispatchedEvent)).toBe(true); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                  // router navigation is async.
 | 
					
						
							|  |  |  |                  router.subscribe((_) => { | 
					
						
							| 
									
										
										
										
											2016-02-19 11:49:31 -08:00
										 |  |  |                    expect((<SpyLocation>location).urlChanges).toEqual(['/user']); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                }); | 
					
						
							| 
									
										
										
										
											2015-09-09 16:41:11 +02:00
										 |  |  |          })); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should navigate to link hrefs in presence of base href', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |          inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2016-02-19 11:49:31 -08:00
										 |  |  |            (<SpyLocation>location).setBaseHref('/base'); | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |            compile('<a href="hello" [routerLink]="[\'./User\']"></a>') | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                .then((_) => router.config([new Route( | 
					
						
							|  |  |  |                          {path: '/user', component: UserCmp, name: 'User'})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |                .then((_) => router.navigateByUrl('/a/b')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                  fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-03 16:14:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                  var dispatchedEvent = clickOnElement(fixture); | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |                  expect(getDOM().isPrevented(dispatchedEvent)).toBe(true); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                  // router navigation is async.
 | 
					
						
							|  |  |  |                  router.subscribe((_) => { | 
					
						
							| 
									
										
										
										
											2016-02-19 11:49:31 -08:00
										 |  |  |                    expect((<SpyLocation>location).urlChanges).toEqual(['/base/user']); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                }); | 
					
						
							| 
									
										
										
										
											2015-09-09 16:41:11 +02:00
										 |  |  |          })); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-30 10:52:04 -07:00
										 |  |  | function getHref(tc: ComponentFixture<any>) { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |   return getDOM().getAttribute(tc.debugElement.query(By.css('a')).nativeElement, 'href'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-08 13:36:48 -08:00
										 |  |  | @Component({selector: 'my-comp', template: '', directives: [ROUTER_DIRECTIVES]}) | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | class MyComp7 { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |   name: any /** TODO #9100 */; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | @Component({selector: 'user-cmp', template: 'hello {{user}}'}) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | class UserCmp { | 
					
						
							|  |  |  |   user: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { this.user = params.get('name'); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:24 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'page-cmp', | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |   template: | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       `page #{{pageNumber}} | <a href="hello" [routerLink]="[\'../Page\', {number: nextPage}]">next</a>`, | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |   directives: [RouterLink] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | class SiblingPageCmp { | 
					
						
							|  |  |  |   pageNumber: number; | 
					
						
							|  |  |  |   nextPage: number; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { | 
					
						
							|  |  |  |     this.pageNumber = NumberWrapper.parseInt(params.get('number'), 10); | 
					
						
							|  |  |  |     this.nextPage = this.pageNumber + 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:24 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'page-cmp', | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |   template: | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |       `page #{{pageNumber}} | <a href="hello" [routerLink]="[\'Page\', {number: nextPage}]">next</a>`, | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |   directives: [RouterLink] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | class NoPrefixSiblingPageCmp { | 
					
						
							|  |  |  |   pageNumber: number; | 
					
						
							|  |  |  |   nextPage: number; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { | 
					
						
							|  |  |  |     this.pageNumber = NumberWrapper.parseInt(params.get('number'), 10); | 
					
						
							|  |  |  |     this.nextPage = this.pageNumber + 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												refactor(router): improve recognition and generation pipeline
This is a big change. @matsko also deserves much of the credit for the implementation.
Previously, `ComponentInstruction`s held all the state for async components.
Now, we introduce several subclasses for `Instruction` to describe each type of navigation.
BREAKING CHANGE:
Redirects now use the Link DSL syntax. Before:
```
@RouteConfig([
	{ path: '/foo', redirectTo: '/bar' },
	{ path: '/bar', component: BarCmp }
])
```
After:
```
@RouteConfig([
	{ path: '/foo', redirectTo: ['Bar'] },
	{ path: '/bar', component: BarCmp, name: 'Bar' }
])
```
BREAKING CHANGE:
This also introduces `useAsDefault` in the RouteConfig, which makes cases like lazy-loading
and encapsulating large routes with sub-routes easier.
Previously, you could use `redirectTo` like this to expand a URL like `/tab` to `/tab/posts`:
@RouteConfig([
	{ path: '/tab', redirectTo: '/tab/users' }
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
Now the recommended way to handle this is case is to use `useAsDefault` like so:
```
@RouteConfig([
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
@RouteConfig([
	{ path: '/posts', component: PostsCmp, useAsDefault: true, name: 'Posts' },
	{ path: '/users', component: UsersCmp, name: 'Users' }
])
TabsCmp { ... }
```
In the above example, you can write just `['/Tab']` and the route `Users` is automatically selected as a child route.
Closes #4728
Closes #4228
Closes #4170
Closes #4490
Closes #4694
Closes #5200
Closes #5475
											
										 
											2015-11-23 18:07:37 -08:00
										 |  |  | @Component({selector: 'hello-cmp', template: 'hello'}) | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | class HelloCmp { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												refactor(router): improve recognition and generation pipeline
This is a big change. @matsko also deserves much of the credit for the implementation.
Previously, `ComponentInstruction`s held all the state for async components.
Now, we introduce several subclasses for `Instruction` to describe each type of navigation.
BREAKING CHANGE:
Redirects now use the Link DSL syntax. Before:
```
@RouteConfig([
	{ path: '/foo', redirectTo: '/bar' },
	{ path: '/bar', component: BarCmp }
])
```
After:
```
@RouteConfig([
	{ path: '/foo', redirectTo: ['Bar'] },
	{ path: '/bar', component: BarCmp, name: 'Bar' }
])
```
BREAKING CHANGE:
This also introduces `useAsDefault` in the RouteConfig, which makes cases like lazy-loading
and encapsulating large routes with sub-routes easier.
Previously, you could use `redirectTo` like this to expand a URL like `/tab` to `/tab/posts`:
@RouteConfig([
	{ path: '/tab', redirectTo: '/tab/users' }
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
Now the recommended way to handle this is case is to use `useAsDefault` like so:
```
@RouteConfig([
	{ path: '/tab', component: TabsCmp, name: 'Tab' }
])
AppCmp { ... }
@RouteConfig([
	{ path: '/posts', component: PostsCmp, useAsDefault: true, name: 'Posts' },
	{ path: '/users', component: UsersCmp, name: 'Users' }
])
TabsCmp { ... }
```
In the above example, you can write just `['/Tab']` and the route `Users` is automatically selected as a child route.
Closes #4728
Closes #4228
Closes #4170
Closes #4490
Closes #4694
Closes #5200
Closes #5475
											
										 
											2015-11-23 18:07:37 -08:00
										 |  |  | @Component({selector: 'hello2-cmp', template: 'hello2'}) | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | class Hello2Cmp { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 14:50:41 -07:00
										 |  |  | function parentCmpLoader() { | 
					
						
							|  |  |  |   return PromiseWrapper.resolve(ParentCmp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:24 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'parent-cmp', | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |   template: `{ <a [routerLink]="['./Grandchild']" class="grandchild-link">Grandchild</a>
 | 
					
						
							|  |  |  |                <a [routerLink]="['./BetterGrandchild']" class="better-grandchild-link">Better Grandchild</a> | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  |                <router-outlet></router-outlet> }`, | 
					
						
							|  |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | @RouteConfig([ | 
					
						
							| 
									
										
										
										
											2015-10-25 15:00:27 +05:30
										 |  |  |   new Route({path: '/grandchild', component: HelloCmp, name: 'Grandchild'}), | 
					
						
							|  |  |  |   new Route({path: '/better-grandchild', component: Hello2Cmp, name: 'BetterGrandchild'}) | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  | ]) | 
					
						
							|  |  |  | class ParentCmp { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:24 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'book-cmp', | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |   template: `<a href="hello" [routerLink]="[\'./Page\', {number: 100}]">{{title}}</a> |
 | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |     <router-outlet></router-outlet>`, | 
					
						
							| 
									
										
										
										
											2015-08-30 21:27:11 -07:00
										 |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-10-25 15:00:27 +05:30
										 |  |  | @RouteConfig([new Route({path: '/page/:number', component: SiblingPageCmp, name: 'Page'})]) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | class BookCmp { | 
					
						
							|  |  |  |   title: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { this.title = params.get('title'); } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:24 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'book-cmp', | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |   template: `<a href="hello" [routerLink]="[\'Page\', {number: 100}]">{{title}}</a> |
 | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |     <router-outlet></router-outlet>`, | 
					
						
							|  |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-10-25 15:00:27 +05:30
										 |  |  | @RouteConfig([new Route({path: '/page/:number', component: SiblingPageCmp, name: 'Page'})]) | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  | class NoPrefixBookCmp { | 
					
						
							|  |  |  |   title: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { this.title = params.get('title'); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:24 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'book-cmp', | 
					
						
							| 
									
										
										
										
											2015-11-23 16:02:19 -08:00
										 |  |  |   template: `<a href="hello" [routerLink]="[\'Book\', {number: 100}]">{{title}}</a> |
 | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  |     <router-outlet></router-outlet>`, | 
					
						
							|  |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-10-25 15:00:27 +05:30
										 |  |  | @RouteConfig([new Route({path: '/page/:number', component: SiblingPageCmp, name: 'Book'})]) | 
					
						
							| 
									
										
										
										
											2015-10-26 17:18:08 +00:00
										 |  |  | class AmbiguousBookCmp { | 
					
						
							|  |  |  |   title: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { this.title = params.get('title'); } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:10 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:24 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'aux-cmp', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |   template: `<a [routerLink]="[\'./Hello\', [ \'Aside\' ] ]">aside</a> |
 | 
					
						
							| 
									
										
										
										
											2015-11-23 18:07:10 -08:00
										 |  |  |     <router-outlet></router-outlet> | aside <router-outlet name="aside"></router-outlet>`, | 
					
						
							|  |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | @RouteConfig([ | 
					
						
							|  |  |  |   new Route({path: '/', component: HelloCmp, name: 'Hello'}), | 
					
						
							|  |  |  |   new AuxRoute({path: '/aside', component: Hello2Cmp, name: 'Aside'}) | 
					
						
							|  |  |  | ]) | 
					
						
							|  |  |  | class AuxLinkCmp { | 
					
						
							|  |  |  | } |