refactor(router): remove deprecated apis (#10658)
This commit is contained in:
parent
f7ff6c5a12
commit
24e280a21a
|
@ -7,16 +7,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
export {ExtraOptions, provideRouterConfig, provideRoutes} from './src/common_router_providers';
|
export {Data, LoadChildren, LoadChildrenCallback, ResolveData, Route, Routes} from './src/config';
|
||||||
export {Data, LoadChildren, LoadChildrenCallback, ResolveData, Route, RouterConfig, Routes} from './src/config';
|
|
||||||
export {RouterLink, RouterLinkWithHref} from './src/directives/router_link';
|
export {RouterLink, RouterLinkWithHref} from './src/directives/router_link';
|
||||||
export {RouterLinkActive} from './src/directives/router_link_active';
|
export {RouterLinkActive} from './src/directives/router_link_active';
|
||||||
export {RouterOutlet} from './src/directives/router_outlet';
|
export {RouterOutlet} from './src/directives/router_outlet';
|
||||||
export {CanActivate, CanActivateChild, CanDeactivate, CanLoad, Resolve} from './src/interfaces';
|
export {CanActivate, CanActivateChild, CanDeactivate, CanLoad, Resolve} from './src/interfaces';
|
||||||
export {Event, NavigationCancel, NavigationEnd, NavigationError, NavigationExtras, NavigationStart, Router, RoutesRecognized} from './src/router';
|
export {Event, NavigationCancel, NavigationEnd, NavigationError, NavigationExtras, NavigationStart, Router, RoutesRecognized} from './src/router';
|
||||||
export {ROUTER_DIRECTIVES, RouterModule} from './src/router_module';
|
export {ExtraOptions, ROUTER_DIRECTIVES, RouterModule, provideRoutes} from './src/router_module';
|
||||||
export {RouterOutletMap} from './src/router_outlet_map';
|
export {RouterOutletMap} from './src/router_outlet_map';
|
||||||
export {provideRouter} from './src/router_providers';
|
|
||||||
export {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot} from './src/router_state';
|
export {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot} from './src/router_state';
|
||||||
export {PRIMARY_OUTLET, Params} from './src/shared';
|
export {PRIMARY_OUTLET, Params} from './src/shared';
|
||||||
export {DefaultUrlSerializer, UrlSegment, UrlSerializer, UrlTree} from './src/url_tree';
|
export {DefaultUrlSerializer, UrlSegment, UrlSerializer, UrlTree} from './src/url_tree';
|
||||||
|
|
|
@ -285,8 +285,7 @@ function match(segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment
|
||||||
const noMatch =
|
const noMatch =
|
||||||
{matched: false, consumedSegments: <any[]>[], lastChild: 0, positionalParamSegments: {}};
|
{matched: false, consumedSegments: <any[]>[], lastChild: 0, positionalParamSegments: {}};
|
||||||
if (route.path === '') {
|
if (route.path === '') {
|
||||||
if ((route.terminal || route.pathMatch === 'full') &&
|
if ((route.pathMatch === 'full') && (segmentGroup.hasChildren() || segments.length > 0)) {
|
||||||
(segmentGroup.hasChildren() || segments.length > 0)) {
|
|
||||||
return {matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {}};
|
return {matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {}};
|
||||||
} else {
|
} else {
|
||||||
return {matched: true, consumedSegments: [], lastChild: 0, positionalParamSegments: {}};
|
return {matched: true, consumedSegments: [], lastChild: 0, positionalParamSegments: {}};
|
||||||
|
@ -315,7 +314,8 @@ function match(segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route.terminal && (segmentGroup.hasChildren() || currentIndex < segments.length)) {
|
if (route.pathMatch === 'full' &&
|
||||||
|
(segmentGroup.hasChildren() || currentIndex < segments.length)) {
|
||||||
return {matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {}};
|
return {matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,8 +434,7 @@ function containsEmptyPathRedirects(
|
||||||
|
|
||||||
function emptyPathRedirect(
|
function emptyPathRedirect(
|
||||||
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], r: Route): boolean {
|
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], r: Route): boolean {
|
||||||
if ((segmentGroup.hasChildren() || slicedSegments.length > 0) &&
|
if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full')
|
||||||
(r.terminal || r.pathMatch === 'full'))
|
|
||||||
return false;
|
return false;
|
||||||
return r.path === '' && r.redirectTo !== undefined;
|
return r.path === '' && r.redirectTo !== undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';
|
|
||||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, Compiler, ComponentResolver, Injector, NgModuleFactoryLoader, OpaqueToken, SystemJsNgModuleLoader} from '@angular/core';
|
|
||||||
|
|
||||||
import {Route, Routes} from './config';
|
|
||||||
import {Router} from './router';
|
|
||||||
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';
|
|
||||||
import {flatten} from './utils/collection';
|
|
||||||
|
|
||||||
export const ROUTER_CONFIGURATION = new OpaqueToken('ROUTER_CONFIGURATION');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
export interface ExtraOptions {
|
|
||||||
enableTracing?: boolean;
|
|
||||||
useHash?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setupRouter(
|
|
||||||
ref: ApplicationRef, resolver: ComponentResolver, urlSerializer: UrlSerializer,
|
|
||||||
outletMap: RouterOutletMap, location: Location, injector: Injector,
|
|
||||||
loader: NgModuleFactoryLoader, compiler: Compiler, config: Route[][], opts: ExtraOptions = {}) {
|
|
||||||
if (ref.componentTypes.length == 0) {
|
|
||||||
throw new Error('Bootstrap at least one component before injecting Router.');
|
|
||||||
}
|
|
||||||
const componentType = ref.componentTypes[0];
|
|
||||||
const r = new Router(
|
|
||||||
componentType, resolver, urlSerializer, outletMap, location, injector, loader, compiler,
|
|
||||||
flatten(config));
|
|
||||||
|
|
||||||
if (opts.enableTracing) {
|
|
||||||
r.events.subscribe(e => {
|
|
||||||
console.group(`Router Event: ${(<any>e.constructor).name}`);
|
|
||||||
console.log(e.toString());
|
|
||||||
console.log(e);
|
|
||||||
console.groupEnd();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function rootRoute(router: Router): ActivatedRoute {
|
|
||||||
return router.routerState.root;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function initialRouterNavigation(router: Router) {
|
|
||||||
return () => { router.initialNavigation(); };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of {@link Provider}s. To use the router, you must add this to your application.
|
|
||||||
*
|
|
||||||
* ### Example
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
|
||||||
* class AppCmp {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* const config = [
|
|
||||||
* {path: 'home', component: Home}
|
|
||||||
* ];
|
|
||||||
*
|
|
||||||
* bootstrap(AppCmp, [provideRouter(config)]);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @deprecated use RouterModule instead
|
|
||||||
*/
|
|
||||||
export function provideRouter(routes: Routes, config: ExtraOptions = {}): any[] {
|
|
||||||
return [
|
|
||||||
provideRoutes(routes),
|
|
||||||
|
|
||||||
{provide: ROUTER_CONFIGURATION, useValue: config}, Location,
|
|
||||||
{provide: LocationStrategy, useClass: PathLocationStrategy},
|
|
||||||
{provide: UrlSerializer, useClass: DefaultUrlSerializer},
|
|
||||||
|
|
||||||
{
|
|
||||||
provide: Router,
|
|
||||||
useFactory: setupRouter,
|
|
||||||
deps: [
|
|
||||||
ApplicationRef, ComponentResolver, UrlSerializer, RouterOutletMap, Location, Injector,
|
|
||||||
NgModuleFactoryLoader, Compiler, ROUTES, ROUTER_CONFIGURATION
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
RouterOutletMap, {provide: ActivatedRoute, useFactory: rootRoute, deps: [Router]},
|
|
||||||
|
|
||||||
// Trigger initial navigation
|
|
||||||
provideRouterInitializer(), {provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function provideRouterInitializer() {
|
|
||||||
return {
|
|
||||||
provide: APP_BOOTSTRAP_LISTENER,
|
|
||||||
multi: true,
|
|
||||||
useFactory: initialRouterNavigation,
|
|
||||||
deps: [Router]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Router configuration.
|
|
||||||
*
|
|
||||||
* ### Example
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* @NgModule({providers: [
|
|
||||||
* provideRoutes([{path: 'home', component: Home}])
|
|
||||||
* ]})
|
|
||||||
* class LazyLoadedModule {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
export function provideRoutes(routes: Routes): any {
|
|
||||||
return [
|
|
||||||
{provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes},
|
|
||||||
{provide: ROUTES, multi: true, useValue: routes}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Router configuration.
|
|
||||||
*
|
|
||||||
* ### Example
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* @NgModule({providers: [
|
|
||||||
* provideRouterOptions({enableTracing: true})
|
|
||||||
* ]})
|
|
||||||
* class LazyLoadedModule {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
export function provideRouterConfig(config: ExtraOptions): any {
|
|
||||||
return {provide: ROUTER_CONFIGURATION, useValue: config};
|
|
||||||
}
|
|
|
@ -9,230 +9,6 @@
|
||||||
import {Type} from '@angular/core';
|
import {Type} from '@angular/core';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `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.
|
|
||||||
*
|
|
||||||
* @deprecated use Routes
|
|
||||||
*/
|
|
||||||
export type RouterConfig = Route[];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `Routes` 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:
|
||||||
*
|
*
|
||||||
|
@ -491,13 +267,8 @@ export type LoadChildren = string | LoadChildrenCallback;
|
||||||
*/
|
*/
|
||||||
export interface Route {
|
export interface Route {
|
||||||
path?: string;
|
path?: string;
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated - use `pathMatch` instead
|
|
||||||
*/
|
|
||||||
terminal?: boolean;
|
|
||||||
pathMatch?: string;
|
pathMatch?: string;
|
||||||
component?: Type<any>|string;
|
component?: Type<any>;
|
||||||
redirectTo?: string;
|
redirectTo?: string;
|
||||||
outlet?: string;
|
outlet?: string;
|
||||||
canActivate?: any[];
|
canActivate?: any[];
|
||||||
|
@ -546,8 +317,7 @@ function validateNode(route: Route): void {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Invalid route configuration of route '${route.path}': path cannot start with a slash`);
|
`Invalid route configuration of route '${route.path}': path cannot start with a slash`);
|
||||||
}
|
}
|
||||||
if (route.path === '' && route.redirectTo !== undefined &&
|
if (route.path === '' && route.redirectTo !== undefined && route.pathMatch === undefined) {
|
||||||
(route.terminal === undefined && route.pathMatch === undefined)) {
|
|
||||||
const exp =
|
const exp =
|
||||||
`The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
`The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|
|
@ -84,23 +84,10 @@ export class RouterOutlet implements OnDestroy {
|
||||||
const component: any = <any>snapshot._routeConfig.component;
|
const component: any = <any>snapshot._routeConfig.component;
|
||||||
|
|
||||||
let factory: ComponentFactory<any>;
|
let factory: ComponentFactory<any>;
|
||||||
try {
|
if (loadedResolver) {
|
||||||
if (typeof component === 'string') {
|
factory = loadedResolver.resolveComponentFactory(component);
|
||||||
factory = snapshot._resolvedComponentFactory;
|
} else {
|
||||||
} else if (loadedResolver) {
|
factory = this.resolver.resolveComponentFactory(component);
|
||||||
factory = loadedResolver.resolveComponentFactory(component);
|
|
||||||
} else {
|
|
||||||
factory = this.resolver.resolveComponentFactory(component);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (!(e instanceof NoComponentFactoryError)) throw e;
|
|
||||||
const componentName = component ? component.name : null;
|
|
||||||
console.warn(
|
|
||||||
`'${componentName}' not found in entryComponents array. To ensure all components referred
|
|
||||||
to by the Routes are compiled, you must add '${componentName}' to the
|
|
||||||
'entryComponents' array of your application component. This will be required in a future
|
|
||||||
release of the router.`);
|
|
||||||
factory = snapshot._resolvedComponentFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const injector = loadedInjector ? loadedInjector : this.location.parentInjector;
|
const injector = loadedInjector ? loadedInjector : this.location.parentInjector;
|
||||||
|
|
|
@ -182,8 +182,7 @@ function match(
|
||||||
segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment[],
|
segmentGroup: UrlSegmentGroup, route: Route, segments: UrlSegment[],
|
||||||
parent: ActivatedRouteSnapshot) {
|
parent: ActivatedRouteSnapshot) {
|
||||||
if (route.path === '') {
|
if (route.path === '') {
|
||||||
if ((route.terminal || route.pathMatch === 'full') &&
|
if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
|
||||||
(segmentGroup.hasChildren() || segments.length > 0)) {
|
|
||||||
throw new NoMatch();
|
throw new NoMatch();
|
||||||
} else {
|
} else {
|
||||||
const params = parent ? parent.params : {};
|
const params = parent ? parent.params : {};
|
||||||
|
@ -213,7 +212,7 @@ function match(
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((route.terminal || route.pathMatch === 'full') &&
|
if (route.pathMatch === 'full' &&
|
||||||
(segmentGroup.hasChildren() || currentIndex < segments.length)) {
|
(segmentGroup.hasChildren() || currentIndex < segments.length)) {
|
||||||
throw new NoMatch();
|
throw new NoMatch();
|
||||||
}
|
}
|
||||||
|
@ -334,8 +333,7 @@ function containsEmptyPathMatches(
|
||||||
|
|
||||||
function emptyPathMatch(
|
function emptyPathMatch(
|
||||||
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], r: Route): boolean {
|
segmentGroup: UrlSegmentGroup, slicedSegments: UrlSegment[], r: Route): boolean {
|
||||||
if ((segmentGroup.hasChildren() || slicedSegments.length > 0) &&
|
if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full')
|
||||||
(r.terminal || r.pathMatch === 'full'))
|
|
||||||
return false;
|
return false;
|
||||||
return r.path === '' && r.redirectTo === undefined;
|
return r.path === '' && r.redirectTo === undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
|
|
||||||
import 'rxjs/add/operator/map';
|
|
||||||
import 'rxjs/add/operator/toPromise';
|
|
||||||
|
|
||||||
import {ComponentResolver} from '@angular/core';
|
|
||||||
import {Observable} from 'rxjs/Observable';
|
|
||||||
import {forkJoin} from 'rxjs/observable/forkJoin';
|
|
||||||
import {fromPromise} from 'rxjs/observable/fromPromise';
|
|
||||||
|
|
||||||
import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state';
|
|
||||||
import {TreeNode} from './utils/tree';
|
|
||||||
|
|
||||||
export function resolve(
|
|
||||||
resolver: ComponentResolver, state: RouterStateSnapshot): Observable<RouterStateSnapshot> {
|
|
||||||
return resolveNode(resolver, state._root).map(_ => state);
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveNode(
|
|
||||||
resolver: ComponentResolver, node: TreeNode<ActivatedRouteSnapshot>): Observable<any> {
|
|
||||||
if (node.children.length === 0) {
|
|
||||||
return fromPromise(resolveComponent(resolver, <any>node.value).then(factory => {
|
|
||||||
node.value._resolvedComponentFactory = factory;
|
|
||||||
return node.value;
|
|
||||||
}));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const c = node.children.map(c => resolveNode(resolver, c).toPromise());
|
|
||||||
return forkJoin(c).map(_ => resolveComponent(resolver, <any>node.value).then(factory => {
|
|
||||||
node.value._resolvedComponentFactory = factory;
|
|
||||||
return node.value;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveComponent(
|
|
||||||
resolver: ComponentResolver, snapshot: ActivatedRouteSnapshot): Promise<any> {
|
|
||||||
if (snapshot.component && snapshot._routeConfig && typeof snapshot.component === 'string') {
|
|
||||||
return resolver.resolveComponent(<any>snapshot.component);
|
|
||||||
} else {
|
|
||||||
return Promise.resolve(null);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,7 +13,7 @@ import 'rxjs/add/operator/reduce';
|
||||||
import 'rxjs/add/operator/every';
|
import 'rxjs/add/operator/every';
|
||||||
|
|
||||||
import {Location} from '@angular/common';
|
import {Location} from '@angular/common';
|
||||||
import {Compiler, ComponentFactoryResolver, ComponentResolver, Injector, NgModuleFactoryLoader, ReflectiveInjector, Type} from '@angular/core';
|
import {Compiler, ComponentFactoryResolver, Injector, NgModuleFactoryLoader, ReflectiveInjector, Type} from '@angular/core';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
import {Subject} from 'rxjs/Subject';
|
import {Subject} from 'rxjs/Subject';
|
||||||
import {Subscription} from 'rxjs/Subscription';
|
import {Subscription} from 'rxjs/Subscription';
|
||||||
|
@ -26,7 +26,6 @@ import {createRouterState} from './create_router_state';
|
||||||
import {createUrlTree} from './create_url_tree';
|
import {createUrlTree} from './create_url_tree';
|
||||||
import {RouterOutlet} from './directives/router_outlet';
|
import {RouterOutlet} from './directives/router_outlet';
|
||||||
import {recognize} from './recognize';
|
import {recognize} from './recognize';
|
||||||
import {resolve} from './resolve';
|
|
||||||
import {LoadedRouterConfig, RouterConfigLoader} from './router_config_loader';
|
import {LoadedRouterConfig, RouterConfigLoader} from './router_config_loader';
|
||||||
import {RouterOutletMap} from './router_outlet_map';
|
import {RouterOutletMap} from './router_outlet_map';
|
||||||
import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from './router_state';
|
import {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, advanceActivatedRoute, createEmptyState} from './router_state';
|
||||||
|
@ -145,10 +144,9 @@ export class Router {
|
||||||
* Creates the router service.
|
* Creates the router service.
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private rootComponentType: Type<any>, private resolver: ComponentResolver,
|
private rootComponentType: Type<any>, private urlSerializer: UrlSerializer,
|
||||||
private urlSerializer: UrlSerializer, private outletMap: RouterOutletMap,
|
private outletMap: RouterOutletMap, private location: Location, private injector: Injector,
|
||||||
private location: Location, private injector: Injector, loader: NgModuleFactoryLoader,
|
loader: NgModuleFactoryLoader, compiler: Compiler, public config: Routes) {
|
||||||
compiler: Compiler, public config: Routes) {
|
|
||||||
this.resetConfig(config);
|
this.resetConfig(config);
|
||||||
this.routerEvents = new Subject<Event>();
|
this.routerEvents = new Subject<Event>();
|
||||||
this.currentUrlTree = createEmptyUrlTree();
|
this.currentUrlTree = createEmptyUrlTree();
|
||||||
|
@ -380,10 +378,10 @@ export class Router {
|
||||||
this.rootComponentType, this.config, appliedUrl, this.serializeUrl(appliedUrl));
|
this.rootComponentType, this.config, appliedUrl, this.serializeUrl(appliedUrl));
|
||||||
})
|
})
|
||||||
|
|
||||||
.mergeMap((newRouterStateSnapshot) => {
|
.map((newRouterStateSnapshot) => {
|
||||||
this.routerEvents.next(new RoutesRecognized(
|
this.routerEvents.next(new RoutesRecognized(
|
||||||
id, this.serializeUrl(url), this.serializeUrl(appliedUrl), newRouterStateSnapshot));
|
id, this.serializeUrl(url), this.serializeUrl(appliedUrl), newRouterStateSnapshot));
|
||||||
return resolve(this.resolver, newRouterStateSnapshot);
|
return newRouterStateSnapshot;
|
||||||
|
|
||||||
})
|
})
|
||||||
.map((routerStateSnapshot) => {
|
.map((routerStateSnapshot) => {
|
||||||
|
|
|
@ -15,11 +15,6 @@ import {LoadChildren, Route} from './config';
|
||||||
import {flatten, wrapIntoObservable} from './utils/collection';
|
import {flatten, wrapIntoObservable} from './utils/collection';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated use Routes
|
|
||||||
*/
|
|
||||||
export const ROUTER_CONFIG = new OpaqueToken('ROUTER_CONFIG');
|
|
||||||
export const ROUTES = new OpaqueToken('ROUTES');
|
export const ROUTES = new OpaqueToken('ROUTES');
|
||||||
|
|
||||||
export class LoadedRouterConfig {
|
export class LoadedRouterConfig {
|
||||||
|
|
|
@ -7,10 +7,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {APP_BASE_HREF, HashLocationStrategy, Location, LocationStrategy, PathLocationStrategy, PlatformLocation} from '@angular/common';
|
import {APP_BASE_HREF, HashLocationStrategy, Location, LocationStrategy, PathLocationStrategy, PlatformLocation} from '@angular/common';
|
||||||
import {ApplicationRef, Compiler, ComponentResolver, Inject, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, OpaqueToken, Optional, SystemJsNgModuleLoader} from '@angular/core';
|
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, ApplicationRef, Compiler, Inject, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, OpaqueToken, Optional, SystemJsNgModuleLoader} from '@angular/core';
|
||||||
|
|
||||||
import {ExtraOptions, ROUTER_CONFIGURATION, provideRouterConfig, provideRouterInitializer, provideRoutes, rootRoute, setupRouter} from './common_router_providers';
|
import {Route, Routes} from './config';
|
||||||
import {Routes} from './config';
|
|
||||||
import {RouterLink, RouterLinkWithHref} from './directives/router_link';
|
import {RouterLink, RouterLinkWithHref} from './directives/router_link';
|
||||||
import {RouterLinkActive} from './directives/router_link_active';
|
import {RouterLinkActive} from './directives/router_link_active';
|
||||||
import {RouterOutlet} from './directives/router_outlet';
|
import {RouterOutlet} from './directives/router_outlet';
|
||||||
|
@ -19,6 +18,7 @@ import {ROUTES} from './router_config_loader';
|
||||||
import {RouterOutletMap} from './router_outlet_map';
|
import {RouterOutletMap} from './router_outlet_map';
|
||||||
import {ActivatedRoute} from './router_state';
|
import {ActivatedRoute} from './router_state';
|
||||||
import {DefaultUrlSerializer, UrlSerializer} from './url_tree';
|
import {DefaultUrlSerializer, UrlSerializer} from './url_tree';
|
||||||
|
import {flatten} from './utils/collection';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,11 @@ import {DefaultUrlSerializer, UrlSerializer} from './url_tree';
|
||||||
*/
|
*/
|
||||||
export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive];
|
export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @stable
|
||||||
|
*/
|
||||||
|
export const ROUTER_CONFIGURATION = new OpaqueToken('ROUTER_CONFIGURATION');
|
||||||
|
|
||||||
const pathLocationStrategy = {
|
const pathLocationStrategy = {
|
||||||
provide: LocationStrategy,
|
provide: LocationStrategy,
|
||||||
useClass: PathLocationStrategy
|
useClass: PathLocationStrategy
|
||||||
|
@ -41,8 +46,8 @@ export const ROUTER_PROVIDERS: any[] = [
|
||||||
provide: Router,
|
provide: Router,
|
||||||
useFactory: setupRouter,
|
useFactory: setupRouter,
|
||||||
deps: [
|
deps: [
|
||||||
ApplicationRef, ComponentResolver, UrlSerializer, RouterOutletMap, Location, Injector,
|
ApplicationRef, UrlSerializer, RouterOutletMap, Location, Injector, NgModuleFactoryLoader,
|
||||||
NgModuleFactoryLoader, Compiler, ROUTES, ROUTER_CONFIGURATION
|
Compiler, ROUTES, ROUTER_CONFIGURATION
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
RouterOutletMap, {provide: ActivatedRoute, useFactory: rootRoute, deps: [Router]},
|
RouterOutletMap, {provide: ActivatedRoute, useFactory: rootRoute, deps: [Router]},
|
||||||
|
@ -102,4 +107,64 @@ export function provideLocationStrategy(
|
||||||
platformLocationStrategy: PlatformLocation, baseHref: string, options: ExtraOptions = {}) {
|
platformLocationStrategy: PlatformLocation, baseHref: string, options: ExtraOptions = {}) {
|
||||||
return options.useHash ? new HashLocationStrategy(platformLocationStrategy, baseHref) :
|
return options.useHash ? new HashLocationStrategy(platformLocationStrategy, baseHref) :
|
||||||
new PathLocationStrategy(platformLocationStrategy, baseHref);
|
new PathLocationStrategy(platformLocationStrategy, baseHref);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @stable
|
||||||
|
*/
|
||||||
|
export function provideRoutes(routes: Routes): any {
|
||||||
|
return [
|
||||||
|
{provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes},
|
||||||
|
{provide: ROUTES, multi: true, useValue: routes}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @stable
|
||||||
|
*/
|
||||||
|
export interface ExtraOptions {
|
||||||
|
enableTracing?: boolean;
|
||||||
|
useHash?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setupRouter(
|
||||||
|
ref: ApplicationRef, urlSerializer: UrlSerializer, outletMap: RouterOutletMap,
|
||||||
|
location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler,
|
||||||
|
config: Route[][], opts: ExtraOptions = {}) {
|
||||||
|
if (ref.componentTypes.length == 0) {
|
||||||
|
throw new Error('Bootstrap at least one component before injecting Router.');
|
||||||
|
}
|
||||||
|
const componentType = ref.componentTypes[0];
|
||||||
|
const r = new Router(
|
||||||
|
componentType, urlSerializer, outletMap, location, injector, loader, compiler,
|
||||||
|
flatten(config));
|
||||||
|
|
||||||
|
if (opts.enableTracing) {
|
||||||
|
r.events.subscribe(e => {
|
||||||
|
console.group(`Router Event: ${(<any>e.constructor).name}`);
|
||||||
|
console.log(e.toString());
|
||||||
|
console.log(e);
|
||||||
|
console.groupEnd();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rootRoute(router: Router): ActivatedRoute {
|
||||||
|
return router.routerState.root;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initialRouterNavigation(router: Router) {
|
||||||
|
return () => { router.initialNavigation(); };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function provideRouterInitializer() {
|
||||||
|
return {
|
||||||
|
provide: APP_BOOTSTRAP_LISTENER,
|
||||||
|
multi: true,
|
||||||
|
useFactory: initialRouterNavigation,
|
||||||
|
deps: [Router]
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -1,40 +0,0 @@
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {PlatformLocation} from '@angular/common';
|
|
||||||
import {BrowserPlatformLocation} from '@angular/platform-browser';
|
|
||||||
|
|
||||||
import {ExtraOptions, provideRouter as provideRouter_} from './common_router_providers';
|
|
||||||
import {Routes} from './config';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A list of {@link Provider}s. To use the router, you must add this to your application.
|
|
||||||
*
|
|
||||||
* ### Example
|
|
||||||
*
|
|
||||||
* ```
|
|
||||||
* @Component({directives: [ROUTER_DIRECTIVES]})
|
|
||||||
* class AppCmp {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* const router = [
|
|
||||||
* {path: 'home', component: Home}
|
|
||||||
* ];
|
|
||||||
*
|
|
||||||
* bootstrap(AppCmp, [provideRouter(router, {enableTracing: true})]);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @experimental
|
|
||||||
*/
|
|
||||||
export function provideRouter(config: Routes, opts: ExtraOptions = {}): any[] {
|
|
||||||
return [
|
|
||||||
{provide: PlatformLocation, useClass: BrowserPlatformLocation}, ...provideRouter_(config, opts)
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -43,16 +43,6 @@ export class RouterState extends Tree<ActivatedRoute> {
|
||||||
setRouterStateSnapshot<RouterState, ActivatedRoute>(this, root);
|
setRouterStateSnapshot<RouterState, ActivatedRoute>(this, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated (Use root.queryParams)
|
|
||||||
*/
|
|
||||||
get queryParams(): Observable<Params> { return this.root.queryParams; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated (Use root.fragment)
|
|
||||||
*/
|
|
||||||
get fragment(): Observable<string> { return this.root.fragment; }
|
|
||||||
|
|
||||||
toString(): string { return this.snapshot.toString(); }
|
toString(): string { return this.snapshot.toString(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,11 +164,6 @@ export class InheritedResolve {
|
||||||
* @stable
|
* @stable
|
||||||
*/
|
*/
|
||||||
export class ActivatedRouteSnapshot {
|
export class ActivatedRouteSnapshot {
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_resolvedComponentFactory: ComponentFactory<any>;
|
|
||||||
|
|
||||||
/** @internal **/
|
/** @internal **/
|
||||||
_routeConfig: Route;
|
_routeConfig: Route;
|
||||||
|
|
||||||
|
@ -251,16 +236,6 @@ export class RouterStateSnapshot extends Tree<ActivatedRouteSnapshot> {
|
||||||
setRouterStateSnapshot<RouterStateSnapshot, ActivatedRouteSnapshot>(this, root);
|
setRouterStateSnapshot<RouterStateSnapshot, ActivatedRouteSnapshot>(this, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated (Use root.queryParams)
|
|
||||||
*/
|
|
||||||
get queryParams(): Params { return this.root.queryParams; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated (Use root.fragment)
|
|
||||||
*/
|
|
||||||
get fragment(): string { return this.root.fragment; }
|
|
||||||
|
|
||||||
toString(): string { return serializeNode(this._root); }
|
toString(): string { return serializeNode(this._root); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ export class Tree<T> {
|
||||||
get root(): T { return this._root.value; }
|
get root(): T { return this._root.value; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated (use ActivatedRoute.parent instead)
|
* @internal
|
||||||
*/
|
*/
|
||||||
parent(t: T): T {
|
parent(t: T): T {
|
||||||
const p = this.pathFromRoot(t);
|
const p = this.pathFromRoot(t);
|
||||||
|
@ -23,7 +23,7 @@ export class Tree<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated (use ActivatedRoute.children instead)
|
* @internal
|
||||||
*/
|
*/
|
||||||
children(t: T): T[] {
|
children(t: T): T[] {
|
||||||
const n = findNode(t, this._root);
|
const n = findNode(t, this._root);
|
||||||
|
@ -31,7 +31,7 @@ export class Tree<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated (use ActivatedRoute.firstChild instead)
|
* @internal
|
||||||
*/
|
*/
|
||||||
firstChild(t: T): T {
|
firstChild(t: T): T {
|
||||||
const n = findNode(t, this._root);
|
const n = findNode(t, this._root);
|
||||||
|
@ -39,7 +39,7 @@ export class Tree<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @internal
|
||||||
*/
|
*/
|
||||||
siblings(t: T): T[] {
|
siblings(t: T): T[] {
|
||||||
const p = findPath(t, this._root, []);
|
const p = findPath(t, this._root, []);
|
||||||
|
@ -50,7 +50,7 @@ export class Tree<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated (use ActivatedRoute.pathFromRoot instead)
|
* @internal
|
||||||
*/
|
*/
|
||||||
pathFromRoot(t: T): T[] { return findPath(t, this._root, []).map(s => s.value); }
|
pathFromRoot(t: T): T[] { return findPath(t, this._root, []).map(s => s.value); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,7 +414,7 @@ describe('applyRedirects', () => {
|
||||||
children: [
|
children: [
|
||||||
{path: 'b', component: ComponentB}, {path: '', redirectTo: 'b'},
|
{path: 'b', component: ComponentB}, {path: '', redirectTo: 'b'},
|
||||||
{path: 'c', component: ComponentC, outlet: 'aux'},
|
{path: 'c', component: ComponentC, outlet: 'aux'},
|
||||||
{path: '', terminal: true, redirectTo: 'c', outlet: 'aux'}
|
{path: '', pathMatch: 'full', redirectTo: 'c', outlet: 'aux'}
|
||||||
]
|
]
|
||||||
}],
|
}],
|
||||||
'a', (t: UrlTree) => { compareTrees(t, tree('a/(b//aux:c)')); });
|
'a', (t: UrlTree) => { compareTrees(t, tree('a/(b//aux:c)')); });
|
||||||
|
|
|
@ -52,7 +52,7 @@ describe('config', () => {
|
||||||
|
|
||||||
it('should throw when path is missing', () => {
|
it('should throw when path is missing', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
validateConfig([{component: '', redirectTo: 'b'}]);
|
validateConfig([{component: null, redirectTo: 'b'}]);
|
||||||
}).toThrowError(`Invalid route configuration: routes must have path specified`);
|
}).toThrowError(`Invalid route configuration: routes must have path specified`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ describe('config', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when pathPatch is invalid', () => {
|
it('should throw when pathPatch is invalid', () => {
|
||||||
expect(() => { validateConfig([{path: 'a', pathMatch: 'invalid', component: 'b'}]); })
|
expect(() => { validateConfig([{path: 'a', pathMatch: 'invalid', component: ComponentB}]); })
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
/Invalid configuration of route 'a': pathMatch can only be set to 'prefix' or 'full'/);
|
/Invalid configuration of route 'a': pathMatch can only be set to 'prefix' or 'full'/);
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -631,13 +631,13 @@ describe('recognize', () => {
|
||||||
it('should support query params', () => {
|
it('should support query params', () => {
|
||||||
const config = [{path: 'a', component: ComponentA}];
|
const config = [{path: 'a', component: ComponentA}];
|
||||||
checkRecognize(config, 'a?q=11', (s: RouterStateSnapshot) => {
|
checkRecognize(config, 'a?q=11', (s: RouterStateSnapshot) => {
|
||||||
expect(s.queryParams).toEqual({q: '11'});
|
expect(s.root.queryParams).toEqual({q: '11'});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should freeze query params object', () => {
|
it('should freeze query params object', () => {
|
||||||
checkRecognize([{path: 'a', component: ComponentA}], 'a?q=11', (s: RouterStateSnapshot) => {
|
checkRecognize([{path: 'a', component: ComponentA}], 'a?q=11', (s: RouterStateSnapshot) => {
|
||||||
expect(Object.isFrozen(s.queryParams)).toBeTruthy();
|
expect(Object.isFrozen(s.root.queryParams)).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -646,7 +646,7 @@ describe('recognize', () => {
|
||||||
it('should support fragment', () => {
|
it('should support fragment', () => {
|
||||||
const config = [{path: 'a', component: ComponentA}];
|
const config = [{path: 'a', component: ComponentA}];
|
||||||
checkRecognize(
|
checkRecognize(
|
||||||
config, 'a#f1', (s: RouterStateSnapshot) => { expect(s.fragment).toEqual('f1'); });
|
config, 'a#f1', (s: RouterStateSnapshot) => { expect(s.root.fragment).toEqual('f1'); });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {Routes} from '../src/config';
|
|
||||||
import {recognize} from '../src/recognize';
|
|
||||||
import {resolve} from '../src/resolve';
|
|
||||||
import {RouterStateSnapshot} from '../src/router_state';
|
|
||||||
import {DefaultUrlSerializer, UrlSegmentGroup, UrlTree} from '../src/url_tree';
|
|
||||||
|
|
||||||
describe('resolve', () => {
|
|
||||||
it('should resolve components', () => {
|
|
||||||
checkResolve(
|
|
||||||
[{path: 'a', component: 'ComponentA'}], 'a', {ComponentA: 'ResolvedComponentA'},
|
|
||||||
(resolved: RouterStateSnapshot) => {
|
|
||||||
expect(resolved.firstChild(resolved.root)._resolvedComponentFactory)
|
|
||||||
.toEqual('ResolvedComponentA');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not resolve componentless routes', () => {
|
|
||||||
checkResolve([{path: 'a', children: []}], 'a', {}, (resolved: RouterStateSnapshot) => {
|
|
||||||
expect(resolved.firstChild(resolved.root)._resolvedComponentFactory).toEqual(null);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function checkResolve(
|
|
||||||
config: Routes, url: string, resolved: {[k: string]: string}, callback: any): void {
|
|
||||||
const resolver = {
|
|
||||||
resolveComponent: (component: string): Promise<any> => {
|
|
||||||
if (resolved[component]) {
|
|
||||||
return Promise.resolve(resolved[component]);
|
|
||||||
} else {
|
|
||||||
return Promise.reject('unknown component');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
recognize(RootComponent, config, tree(url), url)
|
|
||||||
.mergeMap(s => resolve(<any>resolver, s))
|
|
||||||
.subscribe(callback, e => { throw e; });
|
|
||||||
}
|
|
||||||
|
|
||||||
function tree(url: string): UrlTree {
|
|
||||||
return new DefaultUrlSerializer().parse(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
class RootComponent {}
|
|
||||||
class ComponentA {}
|
|
||||||
class ComponentB {}
|
|
||||||
class ComponentC {}
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import {Location, LocationStrategy} from '@angular/common';
|
import {Location, LocationStrategy} from '@angular/common';
|
||||||
import {MockLocationStrategy, SpyLocation} from '@angular/common/testing';
|
import {MockLocationStrategy, SpyLocation} from '@angular/common/testing';
|
||||||
import {Compiler, ComponentResolver, Injectable, Injector, NgModule, NgModuleFactory, NgModuleFactoryLoader} from '@angular/core';
|
import {Compiler, Injectable, Injector, NgModule, NgModuleFactory, NgModuleFactoryLoader} from '@angular/core';
|
||||||
|
|
||||||
import {Route, Router, RouterOutletMap, UrlSerializer} from '../index';
|
import {Route, Router, RouterOutletMap, UrlSerializer} from '../index';
|
||||||
import {ROUTES} from '../src/router_config_loader';
|
import {ROUTES} from '../src/router_config_loader';
|
||||||
|
@ -39,12 +39,10 @@ export class SpyNgModuleFactoryLoader implements NgModuleFactoryLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupTestingRouter(
|
function setupTestingRouter(
|
||||||
resolver: ComponentResolver, urlSerializer: UrlSerializer, outletMap: RouterOutletMap,
|
urlSerializer: UrlSerializer, outletMap: RouterOutletMap, location: Location,
|
||||||
location: Location, loader: NgModuleFactoryLoader, compiler: Compiler, injector: Injector,
|
loader: NgModuleFactoryLoader, compiler: Compiler, injector: Injector, routes: Route[][]) {
|
||||||
routes: Route[][]) {
|
|
||||||
return new Router(
|
return new Router(
|
||||||
null, resolver, urlSerializer, outletMap, location, injector, loader, compiler,
|
null, urlSerializer, outletMap, location, injector, loader, compiler, flatten(routes));
|
||||||
flatten(routes));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,8 +72,7 @@ function setupTestingRouter(
|
||||||
provide: Router,
|
provide: Router,
|
||||||
useFactory: setupTestingRouter,
|
useFactory: setupTestingRouter,
|
||||||
deps: [
|
deps: [
|
||||||
ComponentResolver, UrlSerializer, RouterOutletMap, Location, NgModuleFactoryLoader,
|
UrlSerializer, RouterOutletMap, Location, NgModuleFactoryLoader, Compiler, Injector, ROUTES
|
||||||
Compiler, Injector, ROUTES
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
"test/url_tree.spec.ts",
|
"test/url_tree.spec.ts",
|
||||||
"test/utils/tree.spec.ts",
|
"test/utils/tree.spec.ts",
|
||||||
"test/url_serializer.spec.ts",
|
"test/url_serializer.spec.ts",
|
||||||
"test/resolve.spec.ts",
|
|
||||||
"test/apply_redirects.spec.ts",
|
"test/apply_redirects.spec.ts",
|
||||||
"test/recognize.spec.ts",
|
"test/recognize.spec.ts",
|
||||||
"test/create_router_state.spec.ts",
|
"test/create_router_state.spec.ts",
|
||||||
|
|
|
@ -127,7 +127,7 @@ export class DraftsCmp {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ROUTER_CONFIG = [
|
export const ROUTER_CONFIG = [
|
||||||
{path: '', terminal: true, redirectTo: 'inbox'}, {path: 'inbox', component: InboxCmp},
|
{path: '', pathMatch: 'full', redirectTo: 'inbox'}, {path: 'inbox', component: InboxCmp},
|
||||||
{path: 'drafts', component: DraftsCmp}, {path: 'detail', loadChildren: 'app/inbox-detail.js'}
|
{path: 'drafts', component: DraftsCmp}, {path: 'detail', loadChildren: 'app/inbox-detail.js'}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ export declare class DefaultUrlSerializer implements UrlSerializer {
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export declare type Event = NavigationStart | NavigationEnd | NavigationCancel | NavigationError | RoutesRecognized;
|
export declare type Event = NavigationStart | NavigationEnd | NavigationCancel | NavigationError | RoutesRecognized;
|
||||||
|
|
||||||
/** @experimental */
|
/** @stable */
|
||||||
export interface ExtraOptions {
|
export interface ExtraOptions {
|
||||||
enableTracing?: boolean;
|
enableTracing?: boolean;
|
||||||
useHash?: boolean;
|
useHash?: boolean;
|
||||||
|
@ -134,13 +134,7 @@ export declare type Params = {
|
||||||
/** @experimental */
|
/** @experimental */
|
||||||
export declare const PRIMARY_OUTLET: string;
|
export declare const PRIMARY_OUTLET: string;
|
||||||
|
|
||||||
/** @experimental */
|
/** @stable */
|
||||||
export declare function provideRouter(config: Routes, opts?: ExtraOptions): any[];
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
export declare function provideRouterConfig(config: ExtraOptions): any;
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
export declare function provideRoutes(routes: Routes): any;
|
export declare function provideRoutes(routes: Routes): any;
|
||||||
|
|
||||||
/** @experimental */
|
/** @experimental */
|
||||||
|
@ -160,7 +154,7 @@ export interface Route {
|
||||||
canDeactivate?: any[];
|
canDeactivate?: any[];
|
||||||
canLoad?: any[];
|
canLoad?: any[];
|
||||||
children?: Route[];
|
children?: Route[];
|
||||||
component?: Type<any> | string;
|
component?: Type<any>;
|
||||||
data?: Data;
|
data?: Data;
|
||||||
loadChildren?: LoadChildren;
|
loadChildren?: LoadChildren;
|
||||||
outlet?: string;
|
outlet?: string;
|
||||||
|
@ -168,7 +162,6 @@ export interface Route {
|
||||||
pathMatch?: string;
|
pathMatch?: string;
|
||||||
redirectTo?: string;
|
redirectTo?: string;
|
||||||
resolve?: ResolveData;
|
resolve?: ResolveData;
|
||||||
/** @deprecated */ terminal?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @stable */
|
/** @stable */
|
||||||
|
@ -178,7 +171,7 @@ export declare class Router {
|
||||||
/** @experimental */ navigated: boolean;
|
/** @experimental */ navigated: boolean;
|
||||||
routerState: RouterState;
|
routerState: RouterState;
|
||||||
url: string;
|
url: string;
|
||||||
constructor(rootComponentType: Type<any>, resolver: ComponentResolver, urlSerializer: UrlSerializer, outletMap: RouterOutletMap, location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Routes);
|
constructor(rootComponentType: Type<any>, urlSerializer: UrlSerializer, outletMap: RouterOutletMap, location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Routes);
|
||||||
createUrlTree(commands: any[], {relativeTo, queryParams, fragment, preserveQueryParams, preserveFragment}?: NavigationExtras): UrlTree;
|
createUrlTree(commands: any[], {relativeTo, queryParams, fragment, preserveQueryParams, preserveFragment}?: NavigationExtras): UrlTree;
|
||||||
dispose(): void;
|
dispose(): void;
|
||||||
initialNavigation(): void;
|
initialNavigation(): void;
|
||||||
|
@ -194,9 +187,6 @@ export declare class Router {
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export declare const ROUTER_DIRECTIVES: (typeof RouterOutlet | typeof RouterLink | typeof RouterLinkWithHref | typeof RouterLinkActive)[];
|
export declare const ROUTER_DIRECTIVES: (typeof RouterOutlet | typeof RouterLink | typeof RouterLinkWithHref | typeof RouterLinkActive)[];
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
export declare type RouterConfig = Route[];
|
|
||||||
|
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export declare class RouterLink {
|
export declare class RouterLink {
|
||||||
fragment: string;
|
fragment: string;
|
||||||
|
@ -275,16 +265,12 @@ export declare class RouterOutletMap {
|
||||||
|
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export declare class RouterState extends Tree<ActivatedRoute> {
|
export declare class RouterState extends Tree<ActivatedRoute> {
|
||||||
/** @deprecated */ fragment: Observable<string>;
|
|
||||||
/** @deprecated */ queryParams: Observable<Params>;
|
|
||||||
snapshot: RouterStateSnapshot;
|
snapshot: RouterStateSnapshot;
|
||||||
toString(): string;
|
toString(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @stable */
|
/** @stable */
|
||||||
export declare class RouterStateSnapshot extends Tree<ActivatedRouteSnapshot> {
|
export declare class RouterStateSnapshot extends Tree<ActivatedRouteSnapshot> {
|
||||||
/** @deprecated */ fragment: string;
|
|
||||||
/** @deprecated */ queryParams: Params;
|
|
||||||
url: string;
|
url: string;
|
||||||
toString(): string;
|
toString(): string;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue