| 
									
										
										
										
											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-04-28 17:50:03 -07:00
										 |  |  | import {APP_BASE_HREF, LocationStrategy} from '@angular/common'; | 
					
						
							| 
									
										
										
										
											2016-06-24 12:41:57 -07:00
										 |  |  | import {MockLocationStrategy} from '@angular/common/testing/mock_location_strategy'; | 
					
						
							| 
									
										
											  
											
												feat(testing): add implicit test module
Every test now has an implicit module. It can be configured via `configureModule` (from @angular/core/testing)
to add providers, directives, pipes, ...
The compiler now has to be configured separately via `configureCompiler` (from @angular/core/testing)
to add providers or define whether to use jit.
BREAKING CHANGE:
- Application providers can no longer inject compiler internals (i.e. everything
  from `@angular/compiler). Inject `Compiler` instead. This reflects the
  changes to `bootstrap` for module support (3f55aa609f60f130f1d69188ed057214b1267cb3).
- Compiler providers can no longer be added via `addProviders` / `withProviders`.
  Use the new method `configureCompiler` instead.
- Platform directives / pipes need to be provided via
  `configureModule` and can no longer be provided via the
  `PLATFORM_PIPES` / `PLATFORM_DIRECTIVES` tokens.
- `setBaseTestProviders()` was renamed into `initTestEnvironment` and 
  now takes a `PlatformRef` and a factory for a
  `Compiler`.
- E.g. for the browser platform:
  
  BEFORE:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
      TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
  
  setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
      TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);   
  ```
  AFTER:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {browserTestCompiler, browserDynamicTestPlatform,
      BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
  
  initTestEnvironment(
      browserTestCompiler,
      browserDynamicTestPlatform(),
      BrowserDynamicTestModule);
  ```
- E.g. for the server platform:
  
  BEFORE:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {TEST_SERVER_PLATFORM_PROVIDERS,
      TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
  
  setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
      TEST_SERVER_APPLICATION_PROVIDERS);   
  ```
  AFTER:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {serverTestCompiler, serverTestPlatform,
      ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
  
  initTestEnvironment(
      serverTestCompiler,
      serverTestPlatform(),
      ServerTestModule);
  ```
Related to #9726
Closes #9846
											
										 
											2016-07-04 09:37:30 -07:00
										 |  |  | import {disposePlatform} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2016-06-23 17:10:22 -07:00
										 |  |  | import {ApplicationRef} from '@angular/core/src/application_ref'; | 
					
						
							|  |  |  | import {Console} from '@angular/core/src/console'; | 
					
						
							| 
									
										
										
										
											2016-06-10 10:21:53 -07:00
										 |  |  | import {Component} from '@angular/core/src/metadata'; | 
					
						
							| 
									
										
										
										
											2016-07-11 16:04:32 -07:00
										 |  |  | import {TestComponentBuilder} from '@angular/core/testing'; | 
					
						
							| 
									
										
										
										
											2016-06-23 17:10:22 -07:00
										 |  |  | import {MockApplicationRef, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; | 
					
						
							|  |  |  | import {AsyncTestCompleter} from '@angular/core/testing/testing_internal'; | 
					
						
							|  |  |  | import {bootstrap} from '@angular/platform-browser-dynamic'; | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; | 
					
						
							|  |  |  | import {DOCUMENT} from '@angular/platform-browser/src/dom/dom_tokens'; | 
					
						
							| 
									
										
										
										
											2016-06-23 17:10:22 -07:00
										 |  |  | import {ROUTER_DIRECTIVES, ROUTER_PRIMARY_COMPONENT, ROUTER_PROVIDERS, RouteParams, Router} from '@angular/router-deprecated'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {PromiseWrapper} from '../../src/facade/async'; | 
					
						
							| 
									
										
										
										
											2016-06-10 10:21:53 -07:00
										 |  |  | import {BaseException} from '../../src/facade/exceptions'; | 
					
						
							| 
									
										
										
										
											2016-06-23 17:10:22 -07:00
										 |  |  | import {AuxRoute, Route, RouteConfig} from '../../src/route_config/route_config_decorator'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-21 01:26:43 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-01 22:50:37 -07:00
										 |  |  | // noinspection JSAnnotator
 | 
					
						
							| 
									
										
										
										
											2015-12-15 08:34:44 -08:00
										 |  |  | class DummyConsole implements Console { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |   log(message: any /** TODO #9100 */) {} | 
					
						
							|  |  |  |   warn(message: any /** TODO #9100 */) {} | 
					
						
							| 
									
										
										
										
											2015-12-15 08:34:44 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | export function main() { | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |   describe('router bootstrap', () => { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     beforeEachProviders( | 
					
						
							|  |  |  |         () => [ROUTER_PROVIDERS, {provide: LocationStrategy, useClass: MockLocationStrategy}, { | 
					
						
							|  |  |  |           provide: ApplicationRef, | 
					
						
							|  |  |  |           useClass: MockApplicationRef | 
					
						
							|  |  |  |         }]); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												feat(testing): add implicit test module
Every test now has an implicit module. It can be configured via `configureModule` (from @angular/core/testing)
to add providers, directives, pipes, ...
The compiler now has to be configured separately via `configureCompiler` (from @angular/core/testing)
to add providers or define whether to use jit.
BREAKING CHANGE:
- Application providers can no longer inject compiler internals (i.e. everything
  from `@angular/compiler). Inject `Compiler` instead. This reflects the
  changes to `bootstrap` for module support (3f55aa609f60f130f1d69188ed057214b1267cb3).
- Compiler providers can no longer be added via `addProviders` / `withProviders`.
  Use the new method `configureCompiler` instead.
- Platform directives / pipes need to be provided via
  `configureModule` and can no longer be provided via the
  `PLATFORM_PIPES` / `PLATFORM_DIRECTIVES` tokens.
- `setBaseTestProviders()` was renamed into `initTestEnvironment` and 
  now takes a `PlatformRef` and a factory for a
  `Compiler`.
- E.g. for the browser platform:
  
  BEFORE:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
      TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
  
  setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
      TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);   
  ```
  AFTER:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {browserTestCompiler, browserDynamicTestPlatform,
      BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
  
  initTestEnvironment(
      browserTestCompiler,
      browserDynamicTestPlatform(),
      BrowserDynamicTestModule);
  ```
- E.g. for the server platform:
  
  BEFORE:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {TEST_SERVER_PLATFORM_PROVIDERS,
      TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
  
  setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
      TEST_SERVER_APPLICATION_PROVIDERS);   
  ```
  AFTER:
  ```
  import {setBaseTestProviders} from ‘@angular/core/testing’;
  import {serverTestCompiler, serverTestPlatform,
      ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
  
  initTestEnvironment(
      serverTestCompiler,
      serverTestPlatform(),
      ServerTestModule);
  ```
Related to #9726
Closes #9846
											
										 
											2016-07-04 09:37:30 -07:00
										 |  |  |     beforeEach(() => disposePlatform()); | 
					
						
							|  |  |  |     afterEach(() => disposePlatform()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -07:00
										 |  |  |     // do not refactor out the `bootstrap` functionality. We still want to
 | 
					
						
							| 
									
										
										
										
											2016-04-14 14:52:35 -07:00
										 |  |  |     // keep this test around so we can ensure that bootstrap a router works
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should bootstrap a simple app', | 
					
						
							|  |  |  |        inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |          var fakeDoc = getDOM().createHtmlDocument(); | 
					
						
							|  |  |  |          var el = getDOM().createElement('app-cmp', fakeDoc); | 
					
						
							|  |  |  |          getDOM().appendChild(fakeDoc.body, el); | 
					
						
							| 
									
										
											  
											
												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-08 16:38:52 -07:00
										 |  |  |          bootstrap(AppCmp, [ | 
					
						
							|  |  |  |            ROUTER_PROVIDERS, {provide: ROUTER_PRIMARY_COMPONENT, useValue: AppCmp}, | 
					
						
							|  |  |  |            {provide: LocationStrategy, useClass: MockLocationStrategy}, | 
					
						
							|  |  |  |            {provide: DOCUMENT, useValue: fakeDoc}, {provide: Console, useClass: DummyConsole} | 
					
						
							|  |  |  |          ]).then((applicationRef) => { | 
					
						
							|  |  |  |            var router = applicationRef.instance.router; | 
					
						
							|  |  |  |            router.subscribe((_: any /** TODO #9100 */) => { | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |              expect(el).toHaveText('outer [ hello ]'); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              expect(applicationRef.instance.location.path()).toEqual(''); | 
					
						
							|  |  |  |              async.done(); | 
					
						
							|  |  |  |            }); | 
					
						
							|  |  |  |          }); | 
					
						
							| 
									
										
											  
											
												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
										 |  |  |        })); | 
					
						
							| 
									
										
										
										
											2015-06-08 18:04:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -07:00
										 |  |  |     describe('broken app', () => { | 
					
						
							| 
									
										
										
										
											2016-06-02 17:30:40 -07:00
										 |  |  |       beforeEachProviders(() => [{provide: ROUTER_PRIMARY_COMPONENT, useValue: BrokenAppCmp}]); | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should rethrow exceptions from component constructors', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          inject( | 
					
						
							|  |  |  |              [AsyncTestCompleter, TestComponentBuilder], | 
					
						
							|  |  |  |              (async: AsyncTestCompleter, tcb: TestComponentBuilder) => { | 
					
						
							|  |  |  |                tcb.createAsync(AppCmp).then((fixture) => { | 
					
						
							|  |  |  |                  var router = fixture.debugElement.componentInstance.router; | 
					
						
							|  |  |  |                  PromiseWrapper.catchError(router.navigateByUrl('/cause-error'), (error) => { | 
					
						
							|  |  |  |                    expect(error).toContainError('oops!'); | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                }); | 
					
						
							|  |  |  |              })); | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-06-15 15:41:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04:00
										 |  |  |     describe('back button app', () => { | 
					
						
							| 
									
										
										
										
											2016-06-02 17:30:40 -07:00
										 |  |  |       beforeEachProviders(() => [{provide: ROUTER_PRIMARY_COMPONENT, useValue: HierarchyAppCmp}]); | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should change the url without pushing a new history state for back navigations', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          inject( | 
					
						
							|  |  |  |              [AsyncTestCompleter, TestComponentBuilder], | 
					
						
							|  |  |  |              (async: AsyncTestCompleter, tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                tcb.createAsync(HierarchyAppCmp).then((fixture) => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                  var router = fixture.debugElement.componentInstance.router; | 
					
						
							|  |  |  |                  var position = 0; | 
					
						
							|  |  |  |                  var flipped = false; | 
					
						
							|  |  |  |                  var history = [ | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                    ['/parent/child', 'root [ parent [ hello ] ]', '/super-parent/child'], | 
					
						
							|  |  |  |                    ['/super-parent/child', 'root [ super-parent [ hello2 ] ]', '/parent/child'], | 
					
						
							|  |  |  |                    ['/parent/child', 'root [ parent [ hello ] ]', false] | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                  ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |                  router.subscribe((_: any /** TODO #9100 */) => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                    var location = fixture.debugElement.componentInstance.location; | 
					
						
							|  |  |  |                    var element = fixture.debugElement.nativeElement; | 
					
						
							|  |  |  |                    var path = location.path(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    var entry = history[position]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    expect(path).toEqual(entry[0]); | 
					
						
							|  |  |  |                    expect(element).toHaveText(entry[1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    var nextUrl = entry[2]; | 
					
						
							|  |  |  |                    if (nextUrl == false) { | 
					
						
							|  |  |  |                      flipped = true; | 
					
						
							|  |  |  |                    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    if (flipped && position == 0) { | 
					
						
							|  |  |  |                      async.done(); | 
					
						
							|  |  |  |                      return; | 
					
						
							|  |  |  |                    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    position = position + (flipped ? -1 : 1); | 
					
						
							|  |  |  |                    if (flipped) { | 
					
						
							|  |  |  |                      location.back(); | 
					
						
							|  |  |  |                    } else { | 
					
						
							|  |  |  |                      router.navigateByUrl(nextUrl); | 
					
						
							|  |  |  |                    } | 
					
						
							|  |  |  |                  }); | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                  router.navigateByUrl(history[0][0]); | 
					
						
							|  |  |  |                }); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              }), | 
					
						
							|  |  |  |          1000); | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -07:00
										 |  |  |     describe('hierarchical app', () => { | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  |       beforeEachProviders( | 
					
						
							| 
									
										
										
										
											2016-06-02 17:30:40 -07:00
										 |  |  |           () => { return [{provide: ROUTER_PRIMARY_COMPONENT, useValue: HierarchyAppCmp}]; }); | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should bootstrap an app with a hierarchy', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          inject( | 
					
						
							|  |  |  |              [AsyncTestCompleter, TestComponentBuilder], | 
					
						
							|  |  |  |              (async: AsyncTestCompleter, tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                tcb.createAsync(HierarchyAppCmp).then((fixture) => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                  var router = fixture.debugElement.componentInstance.router; | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |                  router.subscribe((_: any /** TODO #9100 */) => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                    expect(fixture.debugElement.nativeElement) | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                        .toHaveText('root [ parent [ hello ] ]'); | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                    expect(fixture.debugElement.componentInstance.location.path()) | 
					
						
							|  |  |  |                        .toEqual('/parent/child'); | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                  router.navigateByUrl('/parent/child'); | 
					
						
							|  |  |  |                }); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              })); | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-26 13:57:41 +00:00
										 |  |  |       // TODO(btford): mock out level lower than LocationStrategy once that level exists
 | 
					
						
							|  |  |  |       xdescribe('custom app base ref', () => { | 
					
						
							| 
									
										
										
										
											2016-06-02 17:30:40 -07:00
										 |  |  |         beforeEachProviders(() => { return [{provide: APP_BASE_HREF, useValue: '/my/app'}]; }); | 
					
						
							| 
									
										
										
										
											2015-08-26 16:45:03 +02:00
										 |  |  |         it('should bootstrap', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |            inject( | 
					
						
							|  |  |  |                [AsyncTestCompleter, TestComponentBuilder], | 
					
						
							|  |  |  |                (async: AsyncTestCompleter, tcb: TestComponentBuilder) => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                  tcb.createAsync(HierarchyAppCmp).then((fixture) => { | 
					
						
							|  |  |  |                    var router = fixture.debugElement.componentInstance.router; | 
					
						
							|  |  |  |                    router.subscribe((_: any /** TODO #9100 */) => { | 
					
						
							|  |  |  |                      expect(fixture.debugElement.nativeElement) | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |                          .toHaveText('root [ parent [ hello ] ]'); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                      expect(fixture.debugElement.componentInstance.location.path()) | 
					
						
							|  |  |  |                          .toEqual('/my/app/parent/child'); | 
					
						
							|  |  |  |                      async.done(); | 
					
						
							|  |  |  |                    }); | 
					
						
							|  |  |  |                    router.navigateByUrl('/parent/child'); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                })); | 
					
						
							| 
									
										
										
										
											2015-07-21 15:05:08 -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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-21 01:26:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('querystring params app', () => { | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  |       beforeEachProviders( | 
					
						
							| 
									
										
										
										
											2016-06-02 17:30:40 -07:00
										 |  |  |           () => { return [{provide: ROUTER_PRIMARY_COMPONENT, useValue: QueryStringAppCmp}]; }); | 
					
						
							| 
									
										
										
										
											2015-07-21 01:26:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should recognize and return querystring params with the injected RouteParams', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          inject( | 
					
						
							|  |  |  |              [AsyncTestCompleter, TestComponentBuilder], | 
					
						
							|  |  |  |              (async: AsyncTestCompleter, tcb: TestComponentBuilder) => { | 
					
						
							|  |  |  |                tcb.createAsync(QueryStringAppCmp).then((fixture) => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                  var router = fixture.debugElement.componentInstance.router; | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |                  router.subscribe((_: any /** TODO #9100 */) => { | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |                    fixture.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    expect(fixture.debugElement.nativeElement) | 
					
						
							|  |  |  |                        .toHaveText('qParam = search-for-something'); | 
					
						
							|  |  |  |                    /* | 
					
						
							|  |  |  |                    expect(applicationRef.hostComponent.location.path()) | 
					
						
							|  |  |  |                        .toEqual('/qs?q=search-for-something');*/ | 
					
						
							|  |  |  |                    async.done(); | 
					
						
							|  |  |  |                  }); | 
					
						
							|  |  |  |                  router.navigateByUrl('/qs?q=search-for-something'); | 
					
						
							|  |  |  |                  fixture.detectChanges(); | 
					
						
							|  |  |  |                }); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              })); | 
					
						
							| 
									
										
										
										
											2015-07-21 01:26:43 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     describe('activate event on outlet', () => { | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  |       let tcb: TestComponentBuilder = null; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 17:30:40 -07:00
										 |  |  |       beforeEachProviders(() => [{provide: ROUTER_PRIMARY_COMPONENT, useValue: AppCmp}]); | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       beforeEach(inject([TestComponentBuilder], (testComponentBuilder: any /** TODO #9100 */) => { | 
					
						
							|  |  |  |         tcb = testComponentBuilder; | 
					
						
							|  |  |  |       })); | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should get a reference and pass data to components loaded inside of outlets', | 
					
						
							| 
									
										
										
										
											2016-06-09 11:04:15 -07:00
										 |  |  |          inject([AsyncTestCompleter], (async: AsyncTestCompleter) => { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |            tcb.createAsync(AppWithOutletListeners).then(fixture => { | 
					
						
							|  |  |  |              let appInstance = fixture.debugElement.componentInstance; | 
					
						
							|  |  |  |              let router = appInstance.router; | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              router.subscribe((_: any /** TODO #9100 */) => { | 
					
						
							|  |  |  |                fixture.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                expect(appInstance.helloCmp).toBeAnInstanceOf(HelloCmp); | 
					
						
							|  |  |  |                expect(appInstance.helloCmp.message).toBe('Ahoy'); | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                async.done(); | 
					
						
							|  |  |  |              }); | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              // TODO(juliemr): This isn't necessary for the test to pass - figure
 | 
					
						
							|  |  |  |              // out what's going on.
 | 
					
						
							|  |  |  |              // router.navigateByUrl('/rainbow(pony)');
 | 
					
						
							|  |  |  |            }); | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  |          })); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -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: 'hello'}) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | class HelloCmp { | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  |   public message: string; | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -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: 'hello2-cmp', template: 'hello2'}) | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04:00
										 |  |  | class Hello2Cmp { | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  |   public greeting: string; | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04: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: 'app-cmp', | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |   template: `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
										 |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-07-13 16:12:48 -07:00
										 |  |  | @RouteConfig([new Route({path: '/', component: HelloCmp})]) | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | class AppCmp { | 
					
						
							| 
									
										
										
										
											2015-06-22 12:14:19 -07:00
										 |  |  |   constructor(public router: Router, public location: LocationStrategy) {} | 
					
						
							| 
									
										
										
										
											2015-06-15 15:41:09 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'app-cmp', | 
					
						
							|  |  |  |   template: `
 | 
					
						
							|  |  |  |     Hello routing! | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |     <router-outlet (activate)="activateHello($event)"></router-outlet> | 
					
						
							|  |  |  |     <router-outlet (activate)="activateHello2($event)" name="pony"></router-outlet>`, | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | @RouteConfig([ | 
					
						
							|  |  |  |   new Route({path: '/rainbow', component: HelloCmp}), | 
					
						
							|  |  |  |   new AuxRoute({name: 'pony', path: 'pony', component: Hello2Cmp}) | 
					
						
							|  |  |  | ]) | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  | class AppWithOutletListeners { | 
					
						
							|  |  |  |   helloCmp: HelloCmp; | 
					
						
							|  |  |  |   hello2Cmp: Hello2Cmp; | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   constructor(public router: Router, public location: LocationStrategy) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 14:13:44 -08:00
										 |  |  |   activateHello(cmp: HelloCmp) { | 
					
						
							|  |  |  |     this.helloCmp = cmp; | 
					
						
							|  |  |  |     this.helloCmp.message = 'Ahoy'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   activateHello2(cmp: Hello2Cmp) { this.hello2Cmp = cmp; } | 
					
						
							| 
									
										
										
										
											2015-11-06 10:01:03 -08: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: 'parent-cmp', | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |   template: `parent [ <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
										 |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-07-13 16:12:48 -07:00
										 |  |  | @RouteConfig([new Route({path: '/child', component: HelloCmp})]) | 
					
						
							| 
									
										
										
										
											2015-06-15 15:41:09 -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: 'super-parent-cmp', | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |   template: `super-parent [ <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
										 |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04:00
										 |  |  | @RouteConfig([new Route({path: '/child', component: Hello2Cmp})]) | 
					
						
							|  |  |  | class SuperParentCmp { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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: 'app-cmp', | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |   template: `root [ <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
										 |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-07-28 01:46:09 -04:00
										 |  |  | @RouteConfig([ | 
					
						
							|  |  |  |   new Route({path: '/parent/...', component: ParentCmp}), | 
					
						
							|  |  |  |   new Route({path: '/super-parent/...', component: SuperParentCmp}) | 
					
						
							|  |  |  | ]) | 
					
						
							| 
									
										
										
										
											2015-06-15 15:41:09 -07:00
										 |  |  | class HierarchyAppCmp { | 
					
						
							| 
									
										
										
										
											2015-06-22 12:14:19 -07:00
										 |  |  |   constructor(public router: Router, public location: LocationStrategy) {} | 
					
						
							| 
									
										
										
										
											2015-05-29 14:58:41 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-08 18:04:13 -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: 'qs-cmp', template: `qParam = {{q}}`}) | 
					
						
							| 
									
										
										
										
											2015-07-21 01:26:43 -07:00
										 |  |  | class QSCmp { | 
					
						
							|  |  |  |   q: string; | 
					
						
							|  |  |  |   constructor(params: RouteParams) { this.q = params.get('q'); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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: 'app-cmp', | 
					
						
							|  |  |  |   template: `<router-outlet></router-outlet>`, | 
					
						
							|  |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-07-21 01:26:43 -07:00
										 |  |  | @RouteConfig([new Route({path: '/qs', component: QSCmp})]) | 
					
						
							|  |  |  | class QueryStringAppCmp { | 
					
						
							|  |  |  |   constructor(public router: Router, public location: LocationStrategy) {} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | @Component({selector: 'oops-cmp', template: 'oh no'}) | 
					
						
							| 
									
										
										
										
											2015-06-08 18:04:13 -07:00
										 |  |  | class BrokenCmp { | 
					
						
							|  |  |  |   constructor() { throw new BaseException('oops!'); } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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: 'app-cmp', | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  |   template: `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
										 |  |  |   directives: ROUTER_DIRECTIVES | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2015-07-13 16:12:48 -07:00
										 |  |  | @RouteConfig([new Route({path: '/cause-error', component: BrokenCmp})]) | 
					
						
							| 
									
										
										
										
											2015-06-08 18:04:13 -07:00
										 |  |  | class BrokenAppCmp { | 
					
						
							| 
									
										
										
										
											2015-06-22 12:14:19 -07:00
										 |  |  |   constructor(public router: Router, public location: LocationStrategy) {} | 
					
						
							| 
									
										
										
										
											2015-06-08 18:04:13 -07:00
										 |  |  | } |