我创建了以下服务,以便能够将所有路由参数作为ParamMap 获取。它背后的主要思想是递归地解析子路由中的所有参数。
Github 要点
import {Injectable} from '@angular/core';
import {
ActivatedRoute,
Router,
NavigationEnd,
ParamMap,
PRIMARY_OUTLET,
RouterEvent
} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
@Injectable()
export class ParamMapService {
paramMap: Observable<ParamMap>;
constructor(private router: Router,
private route: ActivatedRoute) {
this.paramMap = this.getParamMapObservable();
}
private getParamMap(route: ActivatedRoute): ParamMap {
const map: Map<string, string | string[]> = new Map();
while (route) {
route.snapshot.paramMap.keys.forEach((key) => {
map.set(key, this.getParamMapValue(route.snapshot.paramMap, key));
});
route = route.firstChild;
}
return <ParamMap>{
keys: this.getParamMapKeys(map),
has: this.getParamMapMethodHas(map),
get: this.getParamMapMethodGet(map),
getAll: this.getParamMapMethodGetAll(map)
};
}
private getParamMapMethodGet(map: Map<string, string | string[]>): (name: string) => string | null {
return (name: string): string | null => {
const value = map.get(name);
if (typeof value === 'string') {
return value;
}
if (Array.isArray(value) && value.length) {
return value[0];
}
return null;
};
}
private getParamMapMethodGetAll(map: Map<string, string | string[]>): (name: string) => string[] {
return (name: string): string[] => {
const value = map.get(name);
if (typeof value === 'string') {
return [value];
}
if (Array.isArray(value)) {
return value;
}
return [];
};
}
private getParamMapMethodHas(map: Map<string, string | string[]>): (name: string) => boolean {
return (name: string): boolean => map.has(name);
}
private getParamMapKeys(map: Map<string, string | string[]>): string[] {
return Array.from(map.keys());
}
private getParamMapObservable(): Observable<ParamMap> {
return this.router.events
.filter((event: RouterEvent) => event instanceof NavigationEnd)
.map(() => this.route)
.filter((route: ActivatedRoute) => route.outlet === PRIMARY_OUTLET)
.map((route: ActivatedRoute) => this.getParamMap(route));
}
private getParamMapValue(paramMap: ParamMap, key: string): string | string[] {
return (paramMap.getAll(key).length > 1 ? paramMap.getAll(key) : paramMap.get(key));
}
}
示例用法
id;
constructor(private paramMapService: ParamMapService) {
this.paramMapService.paramMap.subscribe(paramMap => {
this.id = paramMap.get('id');
});
}
笔记
ES6 Map正在服务中使用。要支持旧版浏览器,请执行以下操作之一:
- 取消注释
import 'core-js/es6/map';
,polyfills.ts
或
- 将所有 Map 实例转换为一个简单对象。