给出路线配置
{
path: '/root/:rootId',
children: [{
path: '/child1/:child1Id',
children: [{
path: '/child2/:child2Id
component: TestComponent
}]
}]
}
在TestComponent中,我如何轻松获取所有路径参数。我想知道是否有比
更简单的方法let rootId = route.parent.parent.snapshot.params;
let child1Id = route.parent.snapshot.params;
let child2Id = route.snapshot.params;
这似乎过于多余,特别是如果我观察路线参数可观察而不是通过路线快照访问参数。这个方法看起来也很脆弱,因为它会破坏如果我移动任何路线/参数周围。我习惯于角度ui-router,其中提供了单个对象$ stateParams,所有param数据都可以轻松访问。我从路由树中的单个节点访问路由解析数据时也遇到了这些问题。任何帮助将非常感激。提前致谢
答案 0 :(得分:35)
从Angular 5.2开始,您可以执行路由器配置以将所有参数继承到子状态。如果您对血腥的详细信息感兴趣,请参阅this commit,但这里有它如何为我工作:
无论您何时致电RouterModule.forRoot()
,都要包含一个配置对象,其继承策略设置为always
(默认为emptyOnly
):
import {RouterModule, ExtraOptions} from "@angular/router";
export const routingConfiguration: ExtraOptions = {
paramsInheritanceStrategy: 'always'
};
export const Routing = RouterModule.forRoot(routes, routingConfiguration);
现在当你在一个儿童组件中查看ActivatedRoute
,祖先' params出现在那里(例如activatedRoute.params
)而不是像activatedRoute.parent.parent.parent.params
那样凌乱的东西。您可以直接访问该值(例如activatedRoute.params.value.userId
)或通过activatedRoute.params.subscribe(...)
订阅。
答案 1 :(得分:3)
您需要迭代路段。
像
这样的东西var params = [];
var route = router.routerState.snapshot.root;
do {
params.push(route.params);
route = route.firstChild;
} while(route);
这为您提供了每个路段的params
列表,然后您可以从中读取所需的参数值。
Object.keys(params)
可能会从param
实例中获取所有可用的参数名称。
答案 2 :(得分:1)
/**
* Get all activated route snapshot param under lazy load modules
* @see RouterModule.forChild(routes)
*/
public static getSnapshotParams(route: ActivatedRoute): { [key: string]: string } {
const params: { [key: string]: string } = {};
do {
const param = route.snapshot.params;
for (let key in param) {
params[key] = param[key];
}
route = route.parent;
} while (route);
return params;
}
/**
* Get all activated route stream observable param under lazy load modules
* @see RouterModule.forChild(routes)
* @see Observable
* @see Params
*/
public static getRouteParam(route: ActivatedRoute, routeKey: string): Observable<number> {
const obs: Observable<Params>[] = [];
do {
obs.push(route.params);
route = route.parent;
} while (route);
return merge(...obs).pipe(
filter(param => !!param[routeKey]),
map(param => param[routeKey])
);
}
}
答案 3 :(得分:1)
如果您有一个用例,您需要知道 primary outlet
中路由的组件中 secondary outlet
的参数,此函数从 收集所有 参数递归所有活动插座:
const getParams = (route) => ({
...route.params,
...route.children.reduce((acc, child) =>
({ ...getParams(child), ...acc }), {})
});
getParams(router.routerState.snapshot.root);
如果当前 URL 是 /path/to/42(outlet:path/to/99)
,则结果对象可能是:
{ primaryParam: '42', outletParam: '99' }
对象中的键取决于您在 Angular 中的路由配置。
答案 4 :(得分:0)
constructor(private route: ActivatedRoute) {}
data$ = of(this.route).pipe(
expand(route => of(route['parent'])),
takeWhile(route => !!route['parent']),
pluck('snapshot', 'data'),
reduce(merge));
<强>解释强>
在此处调用expand会为父链中的每个路径创建一个observable。使用Takewhile以便在路由[&#39; parent&#39;]返回null时或在根路由时停止递归。
然后,对于observable中的所有路径,pluck会将每个路由映射到它的snapshot.data&#39;属性。
最后,reduce正在从lodash提供合并函数,以将所有数据对象组合成一个对象。此流将当前路由中的所有数据聚合到父路由
答案 5 :(得分:0)
我已创建以下服务,以便能够将所有路线参数作为ParamMap。它背后的主要思想是递归地解析子路径中的所有参数。
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
行
答案 6 :(得分:0)
角度5:
http
答案 7 :(得分:-1)
我通过这种方式得到了第一条路线:
console.log(this.route.snapshot.firstChild.params)