diff --git a/modules/@angular/router/index.ts b/modules/@angular/router/index.ts index 1cee5c9299..f5f234680e 100644 --- a/modules/@angular/router/index.ts +++ b/modules/@angular/router/index.ts @@ -7,16 +7,16 @@ */ -export {ExtraOptions, provideRoutes, provideRouterConfig} from './src/common_router_providers'; -export {Data, ResolveData, Route, RouterConfig} from './src/config'; +export {ExtraOptions, provideRouterConfig, provideRoutes} from './src/common_router_providers'; +export {Data, ResolveData, Route, RouterConfig, Routes} from './src/config'; export {RouterLink, RouterLinkWithHref} from './src/directives/router_link'; export {RouterLinkActive} from './src/directives/router_link_active'; export {RouterOutlet} from './src/directives/router_outlet'; export {CanActivate, CanDeactivate, Resolve} from './src/interfaces'; export {Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router, RoutesRecognized} from './src/router'; +export {ROUTER_DIRECTIVES, RouterAppModule} from './src/router_app_module'; export {RouterOutletMap} from './src/router_outlet_map'; export {provideRouter} from './src/router_providers'; export {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot} from './src/router_state'; export {PRIMARY_OUTLET, Params} from './src/shared'; -export {RouterAppModule, ROUTER_DIRECTIVES} from './src/router_app_module'; export {DefaultUrlSerializer, UrlPathWithParams, UrlSerializer, UrlTree} from './src/url_tree'; diff --git a/modules/@angular/router/src/apply_redirects.ts b/modules/@angular/router/src/apply_redirects.ts index 711caa9be6..3154eea0ea 100644 --- a/modules/@angular/router/src/apply_redirects.ts +++ b/modules/@angular/router/src/apply_redirects.ts @@ -15,7 +15,7 @@ import {Observer} from 'rxjs/Observer'; import {of } from 'rxjs/observable/of'; import {EmptyError} from 'rxjs/util/EmptyError'; -import {Route, RouterConfig} from './config'; +import {Route, Routes} from './config'; import {RouterConfigLoader} from './router_config_loader'; import {PRIMARY_OUTLET} from './shared'; import {UrlPathWithParams, UrlSegment, UrlTree} from './url_tree'; @@ -38,7 +38,7 @@ function absoluteRedirect(newPaths: UrlPathWithParams[]): Observable } export function applyRedirects( - configLoader: RouterConfigLoader, urlTree: UrlTree, config: RouterConfig): Observable { + configLoader: RouterConfigLoader, urlTree: UrlTree, config: Routes): Observable { return expandSegment(configLoader, config, urlTree.root, PRIMARY_OUTLET) .map(rootSegment => createUrlTree(urlTree, rootSegment)) .catch(e => { @@ -190,8 +190,8 @@ function matchPathsWithParamsAgainstRoute( function getChildConfig(configLoader: RouterConfigLoader, route: Route): Observable { if (route.children) { return of (route.children); - } else if (route.mountChildren) { - return configLoader.load(route.mountChildren).map(r => { + } else if (route.loadChildren) { + return configLoader.load(route.loadChildren).map(r => { (route)._loadedConfig = r; return r.routes; }); diff --git a/modules/@angular/router/src/common_router_providers.ts b/modules/@angular/router/src/common_router_providers.ts index 47262b746c..42128e9242 100644 --- a/modules/@angular/router/src/common_router_providers.ts +++ b/modules/@angular/router/src/common_router_providers.ts @@ -9,14 +9,14 @@ import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common'; import {APP_INITIALIZER, AppModuleFactoryLoader, ApplicationRef, ComponentResolver, Injector, OpaqueToken, SystemJsAppModuleLoader} from '@angular/core'; -import {RouterConfig} from './config'; +import {Routes} from './config'; import {Router} from './router'; -import {ROUTER_CONFIG} from './router_config_loader'; +import {ROUTER_CONFIG, ROUTES} from './router_config_loader'; import {RouterOutletMap} from './router_outlet_map'; import {ActivatedRoute} from './router_state'; import {DefaultUrlSerializer, UrlSerializer} from './url_tree'; -export const ROUTER_OPTIONS = new OpaqueToken('ROUTER_OPTIONS'); +export const ROUTER_CONFIGURATION = new OpaqueToken('ROUTER_CONFIGURATION'); /** * @experimental @@ -26,7 +26,7 @@ export interface ExtraOptions { enableTracing?: boolean; } export function setupRouter( ref: ApplicationRef, resolver: ComponentResolver, urlSerializer: UrlSerializer, outletMap: RouterOutletMap, location: Location, injector: Injector, - loader: AppModuleFactoryLoader, config: RouterConfig, opts: ExtraOptions) { + loader: AppModuleFactoryLoader, config: Routes, opts: ExtraOptions) { if (ref.componentTypes.length == 0) { throw new Error('Bootstrap at least one component before injecting Router.'); } @@ -82,10 +82,12 @@ export function setupRouterInitializer(injector: Injector) { * * @deprecated use RouterAppModule instead */ -export function provideRouter(_config: RouterConfig, _opts: ExtraOptions): any[] { +export function provideRouter(routes: Routes, config: ExtraOptions): any[] { return [ - {provide: ROUTER_CONFIG, useValue: _config}, {provide: ROUTER_OPTIONS, useValue: _opts}, - Location, {provide: LocationStrategy, useClass: PathLocationStrategy}, + {provide: ROUTES, useExisting: ROUTER_CONFIG}, {provide: ROUTER_CONFIG, useValue: routes}, + + {provide: ROUTER_CONFIGURATION, useValue: config}, Location, + {provide: LocationStrategy, useClass: PathLocationStrategy}, {provide: UrlSerializer, useClass: DefaultUrlSerializer}, { @@ -93,7 +95,7 @@ export function provideRouter(_config: RouterConfig, _opts: ExtraOptions): any[] useFactory: setupRouter, deps: [ ApplicationRef, ComponentResolver, UrlSerializer, RouterOutletMap, Location, Injector, - AppModuleFactoryLoader, ROUTER_CONFIG, ROUTER_OPTIONS + AppModuleFactoryLoader, ROUTES, ROUTER_CONFIGURATION ] }, @@ -122,8 +124,8 @@ export function provideRouter(_config: RouterConfig, _opts: ExtraOptions): any[] * * @experimental */ -export function provideRoutes(config: RouterConfig): any { - return {provide: ROUTER_CONFIG, useValue: config}; +export function provideRoutes(routes: Routes): any { + return {provide: ROUTES, useValue: routes}; } /** @@ -142,6 +144,6 @@ export function provideRoutes(config: RouterConfig): any { * * @experimental */ -export function provideRouterConfig(options: ExtraOptions): any { - return {provide: ROUTER_OPTIONS, useValue: options}; +export function provideRouterConfig(config: ExtraOptions): any { + return {provide: ROUTER_CONFIGURATION, useValue: config}; } diff --git a/modules/@angular/router/src/config.ts b/modules/@angular/router/src/config.ts index a84e9745dc..36eb6a4bae 100644 --- a/modules/@angular/router/src/config.ts +++ b/modules/@angular/router/src/config.ts @@ -8,8 +8,9 @@ import {Type} from '@angular/core'; + /** - * `RouterConfig` is an array of route configurations. Each one has the following properties: + * `Routes` is an array of route configurations. Each one has the following properties: * * - *`path`* is a string that uses the route matcher DSL. * - `pathMatch` is a string that specifies the matching strategy. @@ -17,9 +18,9 @@ import {Type} from '@angular/core'; * - `redirectTo` is the url fragment which will replace the current matched segment. * - `outlet` is the name of the outlet the component should be placed into. * - `canActivate` is an array of DI tokens used to look up CanActivate handlers. See {@link - * CanActivate} for more info. + * CanActivate} for more info. * - `canDeactivate` is an array of DI tokens used to look up CanDeactivate handlers. See {@link - * CanDeactivate} for more info. + * CanDeactivate} for more info. * - `data` is additional data provided to the component via `ActivatedRoute`. * - `resolve` is a map of DI tokens used to look up data resolvers. See {@link Resolve} for more * info. @@ -227,12 +228,235 @@ import {Type} from '@angular/core'; * With this configuration in place, navigating to '/parent/10' will create the main child and aux * components. * - * @stable + * @deprecated use Routes */ export type RouterConfig = Route[]; /** - * See {@link RouterConfig} for more details. + * `Routes` is an array of route configurations. Each one has the following properties: + * + * - *`path`* is a string that uses the route matcher DSL. + * - `pathMatch` is a string that specifies the matching strategy. + * - `component` is a component type. + * - `redirectTo` is the url fragment which will replace the current matched segment. + * - `outlet` is the name of the outlet the component should be placed into. + * - `canActivate` is an array of DI tokens used to look up CanActivate handlers. See {@link + * CanActivate} for more info. + * - `canDeactivate` is an array of DI tokens used to look up CanDeactivate handlers. See {@link + * CanDeactivate} for more info. + * - `data` is additional data provided to the component via `ActivatedRoute`. + * - `resolve` is a map of DI tokens used to look up data resolvers. See {@link Resolve} for more + * info. + * - `children` is an array of child route definitions. + * + * ### Simple Configuration + * + * ``` + * [{ + * path: 'team/:id', + * component: Team, + * children: [ + * { + * path: 'user/:name', + * component: User + * } + * ] + * }] + * ``` + * + * When navigating to `/team/11/user/bob`, the router will create the team component with the user + * component in it. + * + * ### Multiple Outlets + * + * ``` + * [{ + * path: 'team/:id', + * component: Team + * }, + * { + * path: 'chat/:user', + * component: Chat + * outlet: aux + * }] + * ``` + * + * When navigating to `/team/11(aux:chat/jim)`, the router will create the team component next to + * the chat component. The chat component will be placed into the aux outlet. + * + * ### Wild Cards + * + * ``` + * [{ + * path: '**', + * component: Sink + * }] + * ``` + * + * Regardless of where you navigate to, the router will instantiate the sink component. + * + * ### Redirects + * + * ``` + * [{ + * path: 'team/:id', + * component: Team, + * children: [ + * { + * path: 'legacy/user/:name', + * redirectTo: 'user/:name' + * }, + * { + * path: 'user/:name', + * component: User + * } + * ] + * }] + * ``` + * + * When navigating to '/team/11/legacy/user/jim', the router will change the url to + * '/team/11/user/jim', and then will instantiate the team component with the user component + * in it. + * + * If the `redirectTo` value starts with a '/', then it is an absolute redirect. E.g., if in the + * example above we change the `redirectTo` to `/user/:name`, the result url will be '/user/jim'. + * + * ### Empty Path + * + * Empty-path route configurations can be used to instantiate components that do not "consume" + * any url segments. Let's look at the following configuration: + * + * ``` + * [{ + * path: 'team/:id', + * component: Team, + * children: [ + * { + * path: '', + * component: AllUsers + * }, + * { + * path: 'user/:name', + * component: User + * } + * ] + * }] + * ``` + * + * When navigating to `/team/11`, the router will instantiate the AllUsers component. + * + * Empty-path routes can have children. + * + * ``` + * [{ + * path: 'team/:id', + * component: Team, + * children: [ + * { + * path: '', + * component: WrapperCmp, + * children: [ + * { + * path: 'user/:name', + * component: User + * } + * ] + * } + * ] + * }] + * ``` + * + * When navigating to `/team/11/user/jim`, the router will instantiate the wrapper component with + * the user component in it. + * + * ### Matching Strategy + * + * By default the router will look at what is left in the url, and check if it starts with + * the specified path (e.g., `/team/11/user` starts with `team/:id`). + * + * We can change the matching strategy to make sure that the path covers the whole unconsumed url, + * which is akin to `unconsumedUrl === path` or `$` regular expressions. + * + * This is particularly important when redirecting empty-path routes. + * + * ``` + * [{ + * path: '', + * pathMatch: 'prefix', //default + * redirectTo: 'main' + * }, + * { + * path: 'main', + * component: Main + * }] + * ``` + * + * Since an empty path is a prefix of any url, even when navigating to '/main', the router will + * still apply the redirect. + * + * If `pathMatch: full` is provided, the router will apply the redirect if and only if navigating to + * '/'. + * + * ``` + * [{ + * path: '', + * pathMatch: 'full', + * redirectTo: 'main' + * }, + * { + * path: 'main', + * component: Main + * }] + * ``` + * + * ### Componentless Routes + * + * It is useful at times to have the ability to share parameters between sibling components. + * + * Say we have two components--ChildCmp and AuxCmp--that we want to put next to each other and both + * of them require some id parameter. + * + * One way to do that would be to have a bogus parent component, so both the siblings can get the id + * parameter from it. This is not ideal. Instead, you can use a componentless route. + * + * ``` + * [{ + * path: 'parent/:id', + * children: [ + * { path: 'a', component: MainChild }, + * { path: 'b', component: AuxChild, outlet: 'aux' } + * ] + * }] + * ``` + * + * So when navigating to `parent/10/(a//aux:b)`, the route will instantiate the main child and aux + * child components next to each other. In this example, the application component + * has to have the primary and aux outlets defined. + * + * The router will also merge the `params`, `data`, and `resolve` of the componentless parent into + * the `params`, `data`, and `resolve` of the children. + * + * This is especially useful when child components are defined as follows: + * + * ``` + * [{ + * path: 'parent/:id', + * children: [ + * { path: '', component: MainChild }, + * { path: '', component: AuxChild, outlet: 'aux' } + * ] + * }] + * ``` + * + * With this configuration in place, navigating to '/parent/10' will create the main child and aux + * components. + * + * @stable use Routes + */ +export type Routes = Route[]; + +/** + * See {@link Routes} for more details. * @stable */ export type Data = { @@ -240,7 +464,7 @@ export type Data = { }; /** - * See {@link RouterConfig} for more details. + * See {@link Routes} for more details. * @stable */ export type ResolveData = { @@ -248,7 +472,7 @@ export type ResolveData = { }; /** - * See {@link RouterConfig} for more details. + * See {@link Routes} for more details. * @stable */ export interface Route { @@ -267,10 +491,10 @@ export interface Route { data?: Data; resolve?: ResolveData; children?: Route[]; - mountChildren?: string; + loadChildren?: string; } -export function validateConfig(config: RouterConfig): void { +export function validateConfig(config: Routes): void { config.forEach(validateNode); } @@ -279,22 +503,22 @@ function validateNode(route: Route): void { throw new Error( `Invalid configuration of route '${route.path}': redirectTo and children cannot be used together`); } - if (!!route.redirectTo && !!route.mountChildren) { + if (!!route.redirectTo && !!route.loadChildren) { throw new Error( - `Invalid configuration of route '${route.path}': redirectTo and mountChildren cannot be used together`); + `Invalid configuration of route '${route.path}': redirectTo and loadChildren cannot be used together`); } - if (!!route.children && !!route.mountChildren) { + if (!!route.children && !!route.loadChildren) { throw new Error( - `Invalid configuration of route '${route.path}': children and mountChildren cannot be used together`); + `Invalid configuration of route '${route.path}': children and loadChildren cannot be used together`); } if (!!route.redirectTo && !!route.component) { throw new Error( `Invalid configuration of route '${route.path}': redirectTo and component cannot be used together`); } if (route.redirectTo === undefined && !route.component && !route.children && - !route.mountChildren) { + !route.loadChildren) { throw new Error( - `Invalid configuration of route '${route.path}': component, redirectTo, children, mountChildren must be provided`); + `Invalid configuration of route '${route.path}': component, redirectTo, children, loadChildren must be provided`); } if (route.path === undefined) { throw new Error(`Invalid route configuration: routes must have path specified`); diff --git a/modules/@angular/router/src/directives/router_outlet.ts b/modules/@angular/router/src/directives/router_outlet.ts index 9cfac24aba..9d3d02f431 100644 --- a/modules/@angular/router/src/directives/router_outlet.ts +++ b/modules/@angular/router/src/directives/router_outlet.ts @@ -79,7 +79,7 @@ export class RouterOutlet { // const componentName = component ? component.name : null; // console.warn( // `'${componentName}' not found in precompile array. To ensure all components referred - // to by the RouterConfig are compiled, you must add '${componentName}' to the + // to by the Routes are compiled, you must add '${componentName}' to the // 'precompile' array of your application component. This will be required in a future // release of the router.`); diff --git a/modules/@angular/router/src/recognize.ts b/modules/@angular/router/src/recognize.ts index 63e5a5880d..ac95d4e178 100644 --- a/modules/@angular/router/src/recognize.ts +++ b/modules/@angular/router/src/recognize.ts @@ -11,7 +11,7 @@ import {Observable} from 'rxjs/Observable'; import {Observer} from 'rxjs/Observer'; import {of } from 'rxjs/observable/of'; -import {Data, ResolveData, Route, RouterConfig} from './config'; +import {Data, ResolveData, Route, Routes} from './config'; import {ActivatedRouteSnapshot, InheritedResolve, RouterStateSnapshot} from './router_state'; import {PRIMARY_OUTLET, Params} from './shared'; import {UrlPathWithParams, UrlSegment, UrlTree, mapChildrenIntoArray} from './url_tree'; @@ -38,9 +38,8 @@ class InheritedFromParent { } } -export function recognize( - rootComponentType: Type, config: RouterConfig, urlTree: UrlTree, - url: string): Observable { +export function recognize(rootComponentType: Type, config: Routes, urlTree: UrlTree, url: string): + Observable { try { const children = processSegment(config, urlTree.root, InheritedFromParent.empty, PRIMARY_OUTLET); @@ -152,7 +151,7 @@ function processPathsWithParamsAgainstRoute( function getChildConfig(route: Route): Route[] { if (route.children) { return route.children; - } else if (route.mountChildren) { + } else if (route.loadChildren) { return (route)._loadedConfig.routes; } else { return []; diff --git a/modules/@angular/router/src/router.ts b/modules/@angular/router/src/router.ts index fc579e6299..781c99ec31 100644 --- a/modules/@angular/router/src/router.ts +++ b/modules/@angular/router/src/router.ts @@ -22,7 +22,7 @@ import {Subscription} from 'rxjs/Subscription'; import {of } from 'rxjs/observable/of'; import {applyRedirects} from './apply_redirects'; -import {ResolveData, RouterConfig, validateConfig} from './config'; +import {ResolveData, Routes, validateConfig} from './config'; import {createRouterState} from './create_router_state'; import {createUrlTree} from './create_url_tree'; import {RouterOutlet} from './directives/router_outlet'; @@ -113,7 +113,7 @@ export type Event = NavigationStart | NavigationEnd | NavigationCancel | Navigat /** * The `Router` is responsible for mapping URLs to components. * - * See {@link RouterConfig) for more details and examples. + * See {@link Routes) for more details and examples. * * @stable */ @@ -123,7 +123,7 @@ export class Router { private locationSubscription: Subscription; private routerEvents: Subject; private navigationId: number = 0; - private config: RouterConfig; + private config: Routes; private futureUrlTree: UrlTree; private configLoader: RouterConfigLoader; @@ -134,7 +134,7 @@ export class Router { private rootComponentType: Type, private resolver: ComponentResolver, private urlSerializer: UrlSerializer, private outletMap: RouterOutletMap, private location: Location, private injector: Injector, loader: AppModuleFactoryLoader, - config: RouterConfig) { + config: Routes) { this.resetConfig(config); this.routerEvents = new Subject(); this.currentUrlTree = createEmptyUrlTree(); @@ -180,7 +180,7 @@ export class Router { * ]); * ``` */ - resetConfig(config: RouterConfig): void { + resetConfig(config: Routes): void { validateConfig(config); this.config = config; } diff --git a/modules/@angular/router/src/router_app_module.ts b/modules/@angular/router/src/router_app_module.ts index 36b87eea56..cd8ebf4b1f 100644 --- a/modules/@angular/router/src/router_app_module.ts +++ b/modules/@angular/router/src/router_app_module.ts @@ -6,20 +6,19 @@ * found in the LICENSE file at https://angular.io/license */ -import {AppModule} from '@angular/core'; import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common'; -import {APP_INITIALIZER, AppModuleFactoryLoader, ApplicationRef, ComponentResolver, Injector, OpaqueToken, SystemJsAppModuleLoader} from '@angular/core'; +import {AppModule, AppModuleFactoryLoader, ApplicationRef, ComponentResolver, Injector, OpaqueToken, SystemJsAppModuleLoader} from '@angular/core'; +import {ROUTER_CONFIGURATION, setupRouter} from './common_router_providers'; +import {RouterLink, RouterLinkWithHref} from './directives/router_link'; +import {RouterLinkActive} from './directives/router_link_active'; +import {RouterOutlet} from './directives/router_outlet'; import {Router} from './router'; -import {setupRouter, ROUTER_OPTIONS} from './common_router_providers'; -import {ROUTER_CONFIG} from './router_config_loader'; +import {ROUTES} from './router_config_loader'; import {RouterOutletMap} from './router_outlet_map'; import {ActivatedRoute} from './router_state'; import {DefaultUrlSerializer, UrlSerializer} from './url_tree'; -import {RouterLink, RouterLinkWithHref} from './directives/router_link'; -import {RouterLinkActive} from './directives/router_link_active'; -import {RouterOutlet} from './directives/router_outlet'; /** * @stable @@ -42,19 +41,18 @@ export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, directives: ROUTER_DIRECTIVES, providers: [ Location, {provide: LocationStrategy, useClass: PathLocationStrategy}, - {provide: UrlSerializer, useClass: DefaultUrlSerializer}, - { + {provide: UrlSerializer, useClass: DefaultUrlSerializer}, { provide: Router, useFactory: setupRouter, deps: [ ApplicationRef, ComponentResolver, UrlSerializer, RouterOutletMap, Location, Injector, - AppModuleFactoryLoader, ROUTER_CONFIG, ROUTER_OPTIONS + AppModuleFactoryLoader, ROUTES, ROUTER_CONFIGURATION ] }, RouterOutletMap, {provide: ActivatedRoute, useFactory: (r: Router) => r.routerState.root, deps: [Router]}, {provide: AppModuleFactoryLoader, useClass: SystemJsAppModuleLoader}, - {provide: ROUTER_OPTIONS, useValue: {enableTracing: false}} + {provide: ROUTER_CONFIGURATION, useValue: {enableTracing: false}} ] }) export class RouterAppModule { diff --git a/modules/@angular/router/src/router_config_loader.ts b/modules/@angular/router/src/router_config_loader.ts index 51903eeaf7..9744f85469 100644 --- a/modules/@angular/router/src/router_config_loader.ts +++ b/modules/@angular/router/src/router_config_loader.ts @@ -12,7 +12,11 @@ import {fromPromise} from 'rxjs/observable/fromPromise'; import {Route} from './config'; +/** + * @deprecated use Routes + */ export const ROUTER_CONFIG = new OpaqueToken('ROUTER_CONFIG'); +export const ROUTES = new OpaqueToken('ROUTES'); export class LoadedRouterConfig { constructor(public routes: Route[], public factoryResolver: ComponentFactoryResolver) {} @@ -24,7 +28,7 @@ export class RouterConfigLoader { load(path: string): Observable { return fromPromise(this.loader.load(path).then(r => { const ref = r.create(); - return new LoadedRouterConfig(ref.injector.get(ROUTER_CONFIG), ref.componentFactoryResolver); + return new LoadedRouterConfig(ref.injector.get(ROUTES), ref.componentFactoryResolver); })); } } \ No newline at end of file diff --git a/modules/@angular/router/src/router_providers.ts b/modules/@angular/router/src/router_providers.ts index ac78d9d16c..8ba974099b 100644 --- a/modules/@angular/router/src/router_providers.ts +++ b/modules/@angular/router/src/router_providers.ts @@ -10,7 +10,7 @@ import {PlatformLocation} from '@angular/common'; import {BrowserPlatformLocation} from '@angular/platform-browser'; import {ExtraOptions, provideRouter as provideRouter_} from './common_router_providers'; -import {RouterConfig} from './config'; +import {Routes} from './config'; /** @@ -33,7 +33,7 @@ import {RouterConfig} from './config'; * * @experimental */ -export function provideRouter(config: RouterConfig, opts: ExtraOptions = {}): any[] { +export function provideRouter(config: Routes, opts: ExtraOptions = {}): any[] { return [ {provide: PlatformLocation, useClass: BrowserPlatformLocation}, ...provideRouter_(config, opts) ]; diff --git a/modules/@angular/router/test/apply_redirects.spec.ts b/modules/@angular/router/test/apply_redirects.spec.ts index dd2a95c400..307d9e7f56 100644 --- a/modules/@angular/router/test/apply_redirects.spec.ts +++ b/modules/@angular/router/test/apply_redirects.spec.ts @@ -2,7 +2,7 @@ import {Observable} from 'rxjs/Observable'; import {of } from 'rxjs/observable/of'; import {applyRedirects} from '../src/apply_redirects'; -import {RouterConfig} from '../src/config'; +import {Routes} from '../src/config'; import {LoadedRouterConfig} from '../src/router_config_loader'; import {DefaultUrlSerializer, UrlSegment, UrlTree, equalPathsWithParams} from '../src/url_tree'; @@ -136,7 +136,7 @@ describe('applyRedirects', () => { const loadedConfig = new LoadedRouterConfig([{path: 'b', component: ComponentB}], 'stubFactoryResolver'); const loader = {load: (p: any) => of (loadedConfig)}; - const config = [{path: 'a', component: ComponentA, mountChildren: 'children'}]; + const config = [{path: 'a', component: ComponentA, loadChildren: 'children'}]; applyRedirects(loader, tree('a/b'), config).forEach(r => { compareTrees(r, tree('/a/b')); @@ -148,7 +148,7 @@ describe('applyRedirects', () => { const loader = { load: (p: any) => new Observable((obs: any) => obs.error(new Error('Loading Error'))) }; - const config = [{path: 'a', component: ComponentA, mountChildren: 'children'}]; + const config = [{path: 'a', component: ComponentA, loadChildren: 'children'}]; applyRedirects(loader, tree('a/b'), config).subscribe(() => {}, (e) => { expect(e.message).toEqual('Loading Error'); @@ -188,7 +188,7 @@ describe('applyRedirects', () => { }); it('should redirect empty path route only when terminal', () => { - const config: RouterConfig = [ + const config: Routes = [ { path: 'a', component: ComponentA, @@ -315,7 +315,7 @@ describe('applyRedirects', () => { }); it('should not create a new child (terminal)', () => { - const config: RouterConfig = [{ + const config: Routes = [{ path: 'a', children: [ {path: 'b', component: ComponentB, children: [{path: 'd', component: ComponentB}]}, @@ -338,7 +338,7 @@ describe('applyRedirects', () => { }); }); -function checkRedirect(config: RouterConfig, url: string, callback: any): void { +function checkRedirect(config: Routes, url: string, callback: any): void { applyRedirects(null, tree(url), config).subscribe(callback, e => { throw e; }); } diff --git a/modules/@angular/router/test/config.spec.ts b/modules/@angular/router/test/config.spec.ts index a86aad9df5..98213b3540 100644 --- a/modules/@angular/router/test/config.spec.ts +++ b/modules/@angular/router/test/config.spec.ts @@ -15,16 +15,16 @@ describe('config', () => { `Invalid configuration of route 'a': redirectTo and children cannot be used together`); }); - it('should throw when redirectTo and mountChildren are used together', () => { - expect(() => { validateConfig([{path: 'a', redirectTo: 'b', mountChildren: 'value'}]); }) + it('should throw when redirectTo and loadChildren are used together', () => { + expect(() => { validateConfig([{path: 'a', redirectTo: 'b', loadChildren: 'value'}]); }) .toThrowError( - `Invalid configuration of route 'a': redirectTo and mountChildren cannot be used together`); + `Invalid configuration of route 'a': redirectTo and loadChildren cannot be used together`); }); - it('should throw when children and mountChildren are used together', () => { - expect(() => { validateConfig([{path: 'a', children: [], mountChildren: 'value'}]); }) + it('should throw when children and loadChildren are used together', () => { + expect(() => { validateConfig([{path: 'a', children: [], loadChildren: 'value'}]); }) .toThrowError( - `Invalid configuration of route 'a': children and mountChildren cannot be used together`); + `Invalid configuration of route 'a': children and loadChildren cannot be used together`); }); it('should throw when component and redirectTo are used together', () => { @@ -42,7 +42,7 @@ describe('config', () => { it('should throw when none of component and children or direct are missing', () => { expect(() => { validateConfig([{path: 'a'}]); }) .toThrowError( - `Invalid configuration of route 'a': component, redirectTo, children, mountChildren must be provided`); + `Invalid configuration of route 'a': component, redirectTo, children, loadChildren must be provided`); }); it('should throw when path starts with a slash', () => { diff --git a/modules/@angular/router/test/create_router_state.spec.ts b/modules/@angular/router/test/create_router_state.spec.ts index 2673118a7e..44897e3fed 100644 --- a/modules/@angular/router/test/create_router_state.spec.ts +++ b/modules/@angular/router/test/create_router_state.spec.ts @@ -1,4 +1,4 @@ -import {RouterConfig} from '../src/config'; +import {Routes} from '../src/config'; import {createRouterState} from '../src/create_router_state'; import {recognize} from '../src/recognize'; import {ActivatedRoute, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from '../src/router_state'; @@ -84,7 +84,7 @@ function advanceNode(node: TreeNode): void { node.children.forEach(advanceNode); } -function createState(config: RouterConfig, url: string): RouterStateSnapshot { +function createState(config: Routes, url: string): RouterStateSnapshot { let res: RouterStateSnapshot; recognize(RootComponent, config, tree(url), url).forEach(s => res = s); return res; diff --git a/modules/@angular/router/test/recognize.spec.ts b/modules/@angular/router/test/recognize.spec.ts index 95e3a79448..bdf38cb2e7 100644 --- a/modules/@angular/router/test/recognize.spec.ts +++ b/modules/@angular/router/test/recognize.spec.ts @@ -1,4 +1,4 @@ -import {RouterConfig} from '../src/config'; +import {Routes} from '../src/config'; import {recognize} from '../src/recognize'; import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../src/router_state'; import {PRIMARY_OUTLET, Params} from '../src/shared'; @@ -529,7 +529,7 @@ describe('recognize', () => { }); }); -function checkRecognize(config: RouterConfig, url: string, callback: any): void { +function checkRecognize(config: Routes, url: string, callback: any): void { recognize(RootComponent, config, tree(url), url).subscribe(callback, e => { throw e; }); } diff --git a/modules/@angular/router/test/resolve.spec.ts b/modules/@angular/router/test/resolve.spec.ts index 63db7c7919..1716a880db 100644 --- a/modules/@angular/router/test/resolve.spec.ts +++ b/modules/@angular/router/test/resolve.spec.ts @@ -1,4 +1,4 @@ -import {RouterConfig} from '../src/config'; +import {Routes} from '../src/config'; import {recognize} from '../src/recognize'; import {resolve} from '../src/resolve'; import {RouterStateSnapshot} from '../src/router_state'; @@ -22,7 +22,7 @@ describe('resolve', () => { }); function checkResolve( - config: RouterConfig, url: string, resolved: {[k: string]: string}, callback: any): void { + config: Routes, url: string, resolved: {[k: string]: string}, callback: any): void { const resolver = { resolveComponent: (component: string): Promise => { if (resolved[component]) { diff --git a/modules/@angular/router/test/router.spec.ts b/modules/@angular/router/test/router.spec.ts index f8aca4656c..d5608764b4 100644 --- a/modules/@angular/router/test/router.spec.ts +++ b/modules/@angular/router/test/router.spec.ts @@ -11,13 +11,12 @@ import {expect} from '@angular/platform-browser/testing/matchers'; import {Observable} from 'rxjs/Observable'; import {of } from 'rxjs/observable/of'; -import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, DefaultUrlSerializer, Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Params, ROUTER_DIRECTIVES, Resolve, Router, RouterConfig, RouterOutletMap, RouterStateSnapshot, RoutesRecognized, UrlSerializer, provideRoutes} from '../index'; +import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, DefaultUrlSerializer, Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Params, ROUTER_DIRECTIVES, Resolve, Router, RouterOutletMap, RouterStateSnapshot, Routes, RoutesRecognized, UrlSerializer, provideRoutes} from '../index'; describe('Integration', () => { beforeEachProviders(() => { - let config: RouterConfig = - [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}]; + let config: Routes = [{path: '', component: BlankCmp}, {path: 'simple', component: SimpleCmp}]; return [ RouterOutletMap, @@ -1124,7 +1123,7 @@ describe('Integration', () => { const fixture = createRoot(tcb, router, RootCmp); - router.resetConfig([{path: 'lazy', mountChildren: 'expected'}]); + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); router.navigateByUrl('/lazy/loaded/child'); advance(fixture); @@ -1142,7 +1141,7 @@ describe('Integration', () => { (loader).expectedPath = 'expected'; const fixture = createRoot(tcb, router, RootCmp); - router.resetConfig([{path: 'lazy', mountChildren: 'invalid'}]); + router.resetConfig([{path: 'lazy', loadChildren: 'invalid'}]); const recordedEvents: any = []; router.events.forEach(e => recordedEvents.push(e)); diff --git a/modules/playground/src/routing/app/inbox-app.ts b/modules/playground/src/routing/app/inbox-app.ts index 6467368b31..b66016dc73 100644 --- a/modules/playground/src/routing/app/inbox-app.ts +++ b/modules/playground/src/routing/app/inbox-app.ts @@ -133,7 +133,7 @@ export const ROUTER_CONFIG = [ {path: '', terminal: true, redirectTo: 'inbox'}, {path: 'inbox', component: InboxCmp}, {path: 'drafts', component: DraftsCmp}, - {path: 'detail', mountChildren: 'app/inbox-detail.js' } + {path: 'detail', loadChildren: 'app/inbox-detail.js' } ]; @Component({ diff --git a/tools/public_api_guard/router/index.d.ts b/tools/public_api_guard/router/index.d.ts index 7cdfc6a3e8..aa7f15c3d0 100644 --- a/tools/public_api_guard/router/index.d.ts +++ b/tools/public_api_guard/router/index.d.ts @@ -91,10 +91,13 @@ export declare type Params = { export declare const PRIMARY_OUTLET: string; /** @experimental */ -export declare function provideRouter(config: RouterConfig, opts?: ExtraOptions): any[]; +export declare function provideRouter(config: Routes, opts?: ExtraOptions): any[]; /** @experimental */ -export declare function provideRoutes(config: RouterConfig): any; +export declare function provideRouterConfig(config: ExtraOptions): any; + +/** @experimental */ +export declare function provideRoutes(routes: Routes): any; /** @experimental */ export interface Resolve { @@ -117,19 +120,24 @@ export declare class Router { events: Observable; routerState: RouterState; url: string; - constructor(rootComponentType: Type, resolver: ComponentResolver, urlSerializer: UrlSerializer, outletMap: RouterOutletMap, location: Location, injector: Injector, loader: AppModuleFactoryLoader, config: RouterConfig); + constructor(rootComponentType: Type, resolver: ComponentResolver, urlSerializer: UrlSerializer, outletMap: RouterOutletMap, location: Location, injector: Injector, loader: AppModuleFactoryLoader, config: Routes); createUrlTree(commands: any[], {relativeTo, queryParams, fragment}?: NavigationExtras): UrlTree; navigate(commands: any[], extras?: NavigationExtras): Promise; navigateByUrl(url: string | UrlTree): Promise; parseUrl(url: string): UrlTree; - resetConfig(config: RouterConfig): void; + resetConfig(config: Routes): void; serializeUrl(url: UrlTree): string; } /** @stable */ export declare const ROUTER_DIRECTIVES: (typeof RouterOutlet | typeof RouterLink | typeof RouterLinkWithHref | typeof RouterLinkActive)[]; -/** @stable */ +/** @experimental */ +export declare class RouterAppModule { + constructor(injector: Injector); +} + +/** @deprecated */ export declare type RouterConfig = Route[]; /** @stable */ @@ -202,6 +210,9 @@ export declare class RouterStateSnapshot extends Tree { toString(): string; } +/** @stable */ +export declare type Routes = Route[]; + /** @stable */ export declare class RoutesRecognized { id: number;