| 
									
										
										
										
											2016-06-23 09:47:54 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {Location} from '@angular/common'; | 
					
						
							|  |  |  | import {Component, Inject, Injector, provide} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2016-07-11 16:04:32 -07:00
										 |  |  | import {ComponentFixture, TestComponentBuilder} from '@angular/core/testing'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {RouteData, RouteParams, Router, RouterLink, RouterOutlet} from '@angular/router-deprecated'; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {PromiseWrapper, TimerWrapper} from '../../src/facade/async'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {AsyncRoute, AuxRoute, Redirect, Route, RouteConfig} from '../../src/route_config/route_config_decorator'; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {RootCmp, TEST_ROUTER_PROVIDERS, compile} from './util'; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  | var cmpInstanceCount: any /** TODO #9100 */; | 
					
						
							|  |  |  | var childCmpInstanceCount: any /** TODO #9100 */; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							| 
									
										
										
										
											2015-08-31 15:53:37 -07:00
										 |  |  |   describe('navigation', () => { | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     var tcb: TestComponentBuilder; | 
					
						
							| 
									
										
										
										
											2016-04-30 10:52:04 -07:00
										 |  |  |     var fixture: ComponentFixture<any>; | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |     var rtr: any /** TODO #9100 */; | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |     beforeEachProviders(() => TEST_ROUTER_PROVIDERS); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     beforeEach(inject( | 
					
						
							|  |  |  |         [TestComponentBuilder, Router], | 
					
						
							|  |  |  |         (tcBuilder: any /** TODO #9100 */, router: any /** TODO #9100 */) => { | 
					
						
							|  |  |  |           tcb = tcBuilder; | 
					
						
							|  |  |  |           rtr = router; | 
					
						
							|  |  |  |           childCmpInstanceCount = 0; | 
					
						
							|  |  |  |           cmpInstanceCount = 0; | 
					
						
							|  |  |  |         })); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |     it('should work in a simple case', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |          compile(tcb) | 
					
						
							|  |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => rtr.config([new Route({path: '/test', component: HelloCmp})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/test')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('hello'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should navigate between components with different parameters', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |          compile(tcb) | 
					
						
							|  |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => rtr.config([new Route({path: '/user/:name', component: UserCmp})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/user/brian')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('hello brian'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              }) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/user/igor')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('hello igor'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should navigate to child routes', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |          compile(tcb, 'outer [ <router-outlet></router-outlet> ]') | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => rtr.config([new Route({path: '/a/...', component: ParentCmp})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/a/b')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-14 11:22:54 -07:00
										 |  |  |     it('should navigate to child routes that capture an empty path', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |          compile(tcb, 'outer [ <router-outlet></router-outlet> ]') | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2015-09-14 11:22:54 -07:00
										 |  |  |              .then((_) => rtr.config([new Route({path: '/a/...', component: ParentCmp})])) | 
					
						
							|  |  |  |              .then((_) => rtr.navigateByUrl('/a')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]'); | 
					
						
							| 
									
										
										
										
											2015-09-14 11:22:54 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-27 21:05:34 +01:00
										 |  |  |     it('should navigate to child routes when the root component has an empty path', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |        inject( | 
					
						
							|  |  |  |            [AsyncTestCompleter, Location], | 
					
						
							|  |  |  |            (async: AsyncTestCompleter, location: any /** TODO #9100 */) => { | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |              compile(tcb, 'outer [ <router-outlet></router-outlet> ]') | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                  .then((rtc) => {fixture = rtc}) | 
					
						
							|  |  |  |                  .then((_) => rtr.config([new Route({path: '/...', component: ParentCmp})])) | 
					
						
							|  |  |  |                  .then((_) => rtr.navigateByUrl('/b')) | 
					
						
							|  |  |  |                  .then((_) => { | 
					
						
							|  |  |  |                    fixture.detectChanges(); | 
					
						
							|  |  |  |                    expect(fixture.debugElement.nativeElement) | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                        .toHaveText('outer [ inner [ hello ] ]'); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                    expect(location.urlChanges).toEqual(['/b']); | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should navigate to child routes of async routes', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |          compile(tcb, 'outer [ <router-outlet></router-outlet> ]') | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2015-09-11 10:07:09 -07:00
										 |  |  |              .then((_) => rtr.config([new AsyncRoute({path: '/a/...', loader: parentLoader})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/a/b')) | 
					
						
							| 
									
										
										
										
											2015-09-11 10:07:09 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('outer [ inner [ hello ] ]'); | 
					
						
							| 
									
										
										
										
											2015-09-11 10:07:09 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-08 01:02:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should replace state when normalized paths are equal', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |        inject( | 
					
						
							|  |  |  |            [AsyncTestCompleter, Location], | 
					
						
							|  |  |  |            (async: AsyncTestCompleter, location: any /** TODO #9100 */) => { | 
					
						
							|  |  |  |              compile(tcb) | 
					
						
							|  |  |  |                  .then((rtc) => {fixture = rtc}) | 
					
						
							|  |  |  |                  .then((_) => location.setInitialPath('/test/')) | 
					
						
							|  |  |  |                  .then((_) => rtr.config([new Route({path: '/test', component: HelloCmp})])) | 
					
						
							|  |  |  |                  .then((_) => rtr.navigateByUrl('/test')) | 
					
						
							|  |  |  |                  .then((_) => { | 
					
						
							|  |  |  |                    fixture.detectChanges(); | 
					
						
							|  |  |  |                    expect(fixture.debugElement.nativeElement).toHaveText('hello'); | 
					
						
							|  |  |  |                    expect(location.urlChanges).toEqual(['replace: /test']); | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |            })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should reuse common parent components', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |          compile(tcb) | 
					
						
							|  |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => rtr.config([new Route({path: '/team/:id/...', component: TeamCmp})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/team/angular/user/rado')) | 
					
						
							| 
									
										
										
										
											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
										 |  |  |                expect(cmpInstanceCount).toBe(1); | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('team angular [ hello rado ]'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              }) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/team/angular/user/victor')) | 
					
						
							| 
									
										
										
										
											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
										 |  |  |                expect(cmpInstanceCount).toBe(1); | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                expect(fixture.debugElement.nativeElement) | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                    .toHaveText('team angular [ hello victor ]'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |     it('should not reuse children when parent components change', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |          compile(tcb) | 
					
						
							|  |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |              .then((_) => rtr.config([new Route({path: '/team/:id/...', component: TeamCmp})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/team/angular/user/rado')) | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |                expect(cmpInstanceCount).toBe(1); | 
					
						
							|  |  |  |                expect(childCmpInstanceCount).toBe(1); | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('team angular [ hello rado ]'); | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |              }) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/team/dart/user/rado')) | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |                expect(cmpInstanceCount).toBe(2); | 
					
						
							|  |  |  |                expect(childCmpInstanceCount).toBe(2); | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('team dart [ hello rado ]'); | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should inject route data into component', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |          compile(tcb) | 
					
						
							|  |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => rtr.config([new Route( | 
					
						
							|  |  |  |                        {path: '/route-data', component: RouteDataCmp, data: {isAdmin: true}})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/route-data')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('true'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should inject route data into component with AsyncRoute', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |          compile(tcb) | 
					
						
							|  |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => rtr.config([new AsyncRoute( | 
					
						
							|  |  |  |                        {path: '/route-data', loader: asyncRouteDataCmp, data: {isAdmin: true}})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/route-data')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(fixture.debugElement.nativeElement).toHaveText('true'); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-30 14:48:58 +02:00
										 |  |  |     it('should inject empty object if the route has no data property', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |          compile(tcb) | 
					
						
							|  |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              .then((_) => rtr.config([new Route( | 
					
						
							|  |  |  |                        {path: '/route-data-default', component: RouteDataCmp})])) | 
					
						
							| 
									
										
										
										
											2015-09-08 21:41:56 -07:00
										 |  |  |              .then((_) => rtr.navigateByUrl('/route-data-default')) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |              .then((_) => { | 
					
						
							| 
									
										
										
										
											2015-10-31 09:50:19 -07:00
										 |  |  |                fixture.detectChanges(); | 
					
						
							|  |  |  |                expect(fixture.debugElement.nativeElement).toHaveText(''); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should fire an event for each activated component', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |          compile(tcb, '<router-outlet (activate)="activatedCmp = $event"></router-outlet>') | 
					
						
							|  |  |  |              .then((rtc) => {fixture = rtc}) | 
					
						
							|  |  |  |              .then((_) => rtr.config([new Route({path: '/test', component: HelloCmp})])) | 
					
						
							|  |  |  |              .then((_) => rtr.navigateByUrl('/test')) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                // Note: need a timeout so that all promises are flushed
 | 
					
						
							|  |  |  |                var completer = PromiseWrapper.completer(); | 
					
						
							|  |  |  |                TimerWrapper.setTimeout(() => { completer.resolve(null); }, 0); | 
					
						
							|  |  |  |                return completer.promise; | 
					
						
							|  |  |  |              }) | 
					
						
							|  |  |  |              .then((_) => { | 
					
						
							|  |  |  |                expect(fixture.componentInstance.activatedCmp).toBeAnInstanceOf(HelloCmp); | 
					
						
							|  |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							|  |  |  |        })); | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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: `{{greeting}}`}) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | class HelloCmp { | 
					
						
							|  |  |  |   greeting: string; | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |   constructor() { this.greeting = 'hello'; } | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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
										 |  |  | function asyncRouteDataCmp() { | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  |   return PromiseWrapper.resolve(RouteDataCmp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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: 'data-cmp', template: `{{myData}}`}) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | class RouteDataCmp { | 
					
						
							| 
									
										
										
										
											2015-09-30 14:48:58 +02:00
										 |  |  |   myData: boolean; | 
					
						
							|  |  |  |   constructor(data: RouteData) { this.myData = data.get('isAdmin'); } | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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: 'user-cmp', template: `hello {{user}}`}) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | class UserCmp { | 
					
						
							|  |  |  |   user: string; | 
					
						
							| 
									
										
										
										
											2015-09-09 12:00:31 -07:00
										 |  |  |   constructor(params: RouteParams) { | 
					
						
							|  |  |  |     childCmpInstanceCount += 1; | 
					
						
							|  |  |  |     this.user = params.get('name'); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 10:07:09 -07:00
										 |  |  | function parentLoader() { | 
					
						
							|  |  |  |   return PromiseWrapper.resolve(ParentCmp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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: 'parent-cmp', | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |   template: `inner [ <router-outlet></router-outlet> ]`, | 
					
						
							| 
									
										
										
										
											2015-10-28 08:59:19 +01:00
										 |  |  |   directives: [RouterOutlet], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | @RouteConfig([ | 
					
						
							|  |  |  |   new Route({path: '/b', component: HelloCmp}), | 
					
						
							|  |  |  |   new Route({path: '/', component: HelloCmp}), | 
					
						
							|  |  |  | ]) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | class ParentCmp { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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: 'team-cmp', | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |   template: `team {{id}} [ <router-outlet></router-outlet> ]`, | 
					
						
							| 
									
										
										
										
											2015-10-28 08:59:19 +01:00
										 |  |  |   directives: [RouterOutlet], | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-08-24 11:24:53 -07:00
										 |  |  | @RouteConfig([new Route({path: '/user/:name', component: UserCmp})]) | 
					
						
							|  |  |  | class TeamCmp { | 
					
						
							|  |  |  |   id: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { | 
					
						
							|  |  |  |     this.id = params.get('id'); | 
					
						
							|  |  |  |     cmpInstanceCount += 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |