如何获得所有路线参数/数据

时间:2017-02-17 14:41:20

标签: angular angular-router

给出路​​线配置

{
   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数据都可以轻松访问。我从路由树中的单个节点访问路由解析数据时也遇到了这些问题。任何帮助将非常感激。提前致谢

8 个答案:

答案 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)

来自所有活动 Outlets 的路由参数

如果您有一个用例,您需要知道 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。它背后的主要思想是递归地解析子路径中的所有参数。

Github gist

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)