使用场景
const routes: Routes = []; // 这里
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
属性列表
export declare type Routes = Route[];
export declare type UrlMatcher = (
segments: UrlSegment[],
group: UrlSegmentGroup,
route: Route) => UrlMatchResult | null;
export declare type LoadChildren = () => Type<any> |
NgModuleFactory<any> |
Observable<Type<any>> |
Promise<NgModuleFactory<any> | Type<any> | any>;
export declare interface Route {
// 这个就不解释了
path?: string;
// 匹配规则,默认值是 prefix
pathMatch?: 'prefix' | 'full';
// path 和 matcher,只能二选一. matcher的用法后面详细写
matcher?: UrlMatcher;
component?: Type<any>;
// Note that no further redirects are evaluated after an absolute redirect
redirectTo?: string;
// outlet对象的名字
outlet?: string;
canActivate?: any[];
canActivateChild?: any[];
canDeactivate?: any[];
canLoad?: any[];
// 通过ActivatedRoute可以获取这个data数据
data?: Data;
// ???
resolve?: ResolveData;
children?: Routes;
/* 懒加载的子路由,常用 :
loadChildren: () => import('./pages/home/home.module')
.then(mod => mod.HomeModule)*/
loadChildren?: LoadChildren;
// 定义guards and resolvers何时生效;
// paramsOrQueryParamsChange 查询参数发生改变的时候
// always 总是
runGuardsAndResolvers?: RunGuardsAndResolvers;
}
关于路由匹配规则:
(componnet省略写,patchMatch都是默认值prefix)
1、config: [ {path: '/demo'}, {path: '/demo/abc'} ]
href: /demo/abc 匹配到第2个
href: /demo/qqq 路由会自动改为 /demo,然后匹配到第一个
2、config: [ {path: '/demo'}, {path: '/demo?a=1'} ]
href: /demo?a=1 路由不会重写, 匹配到第1个
----------------------------分割线----------------------------------------------------
1、matcher 怎么用?
2、outlet 怎么用?
3、resolve 怎么用?
4、runGuardsAndResolvers ?
5、loadChildren 全部参数类型
matcher
1、matcher 是一个function, 参数有三个,(url: UrlSegment[], group:UrlSegmentGroup, route). 前两个参数定义如下,第三个参数就是当前item的Route配置.
第一个参数:urlSegement: 网址段 。例如 href: /demo/abc,那么 参数1 就会是
[ { path: 'demo' }, {path:'abc'} ]
第二个参数:UrlSegmentGroup。假设 href : /home/list/abc, 其中/home是模块home, 那个第一个参数 [{path: 'list}',{path: 'abc'}], 第二个参数 group.segments 会多一个item {path: 'home'}.
export declare class UrlSegment {
/** The path part of a URL segment */
path: string;
/** The matrix parameters associated with a segment */
parameters: {
[name: string]: string;
};
constructor(
/** The path part of a URL segment */
path: string,
/** The matrix parameters associated with a segment */
parameters: {
[name: string]: string;
});
get parameterMap(): ParamMap;
/** @docsNotRequired */
toString(): string;
}
export declare class UrlSegmentGroup {
/** The URL segments of this group. See `UrlSegment` for more information */
segments: UrlSegment[];
/** The list of children of this group */
children: {
[key: string]: UrlSegmentGroup;
};
/** The parent node in the url tree */
parent: UrlSegmentGroup | null;
constructor(
/** The URL segments of this group. See `UrlSegment` for more information */
segments: UrlSegment[],
/** The list of children of this group */
children: {
[key: string]: UrlSegmentGroup;
});
/** Whether the segment has child segments */
hasChildren(): boolean;
/** Number of child segments */
get numberOfChildren(): number;
/** @docsNotRequired */
toString(): string;
}
2、返回值 MatcherResult
return {
consumed: url, // consumed: UrlSegment[];
posParams: {} // posParams可选,{key: value类型需要是UrlSegment}
}
或者
return null;
1、官方给的用例是,从matcher的参数1获取path,根据条件判断返回null或者MatcherResult., 结果就是该配置的component是否显示。
2、根据我的测试,一个Route[]数组,把matcher的项放前面。如果matcher返回null,继续后面的路由匹配;如果matcher返回MatcherResult,则显示matcher这个component. 效果就是,可以通过查询参数来判断是否返回null, 一个路由,可以显示不同的组件。
使用demo:
let config = [
{
matcher: (
url: UrlSegment[],
group: UrlSegmentGroup,
route: Route
) => {
// 一些判断逻辑
let result = true;
return result ? url : null;
},
component: DemoComponent
}
];
outlet
<router-outlet></router-outlet>
<router-outlet name="other"></router-outlet>
const routes = [
{
path: 'home',
component: HomeComponent,
}, {
path: 'details',
component: DetailsComponent,
outlet: 'other',
}
];
1、省略的话,outlet默认是‘primary’
2、对于如下配置,outLet不生效,我不知为啥。官方给的示例说是能用
{path:'', component: xx, children: [
{path:'aa', component: xx, outlet: 'somename'}
]}
3、ActivatedRoute可以获取 outlet的取值。
resolver
A map of DI tokens used to look up data resolvers.用于查找数据解析器的 DI 令牌映射。
接口如果报错,路由会被重置,“/demo” -> “ /”, 原来的/demo路由对应的组件并不会展示。
看看代码就懂了:
// 写 resolve ---------------
@Injectable({ providedIn: 'root' })
class DemoListResolver implements Resolve<User> {
constructor (
private myService: MyHttpService
) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<any>|Promise<any>|any {
return this.myService.getUser('666');
// 这个return到了ActivatedRoute上
// Observable
}
}
// 配置路由 ---------------------
const routes: Routes = [
{
path: '',
component: DemoComponent,
resolve: {
user: DemoListResolver
}
}
];
// demo component --------------------
class DemoComponent {
constructor(
private routeInfo: ActivatedRoute
) {
console.log(this.routeInfo);
// routeInfo.snapshot.data['user'] 这个user就是resolve里面的user
}
}
runGuardsAndResolvers
export declare type RunGuardsAndResolvers = 'pathParamsChange' | 'pathParamsOrQueryParamsChange' | 'paramsChange' | 'paramsOrQueryParamsChange' | 'always' | ((from: ActivatedRouteSnapshot, to: ActivatedRouteSnapshot) => boolean);
- pathParams: /user/:id ??
- queryParams: /user?id=1
- params: ??
By default, guards and resolvers run only when the matrix parameters of the route change.
来点demo:
const routes: Routes = [
{
path: 'demo/:id',
component: DemoComponent,
resolve: {
user: DemoListResolver
},
runGuardsAndResolvers: 'paramsChange'
}
];
/*
默认情况下 paramsChange
/demo/111 -> /demo/233 会触发
/demo/111 -> /demo/111?type=6 不会触发
'pathParamsOrQueryParamsChange' ,'paramsOrQueryParamsChange'
/demo/11?type 5 -> /demo/11?type=666 会触发
*/
loadChildren:
export declare type LoadChildren = LoadChildrenCallback;
export declare type LoadChildrenCallback = () => Type<any> | NgModuleFactory<any> | Observable<Type<any>> | Promise<NgModuleFactory<any> | Type<any> | any>;
翻来翻去,也只找到这么一种用法:
[{
path: 'lazy',
loadChildren: () => import('./lazy-route/lazy.module')
.then(mod => mod.LazyModule)
}];