How to get all route params/data

前端 未结 6 559
执念已碎
执念已碎 2020-12-24 07:20

Given a route config

{
   path: \'/root/:rootId\',
   children: [{
       path: \'/child1/:child1Id\',
       children: [{
           path: \'/child2/:child2         


        
相关标签:
6条回答
  • 2020-12-24 07:56

    You need to iterate the route segments.

    Something like

    var params = [];
    var route = router.routerState.snapshot.root;
    do {
     params.push(route.params); 
     route = route.firstChild;
    } while(route);
    

    This gives you the list of params of each route segment, you then can read the param values from them that you want.

    Object.keys(params) might work to get all available param names from a param instance.

    0 讨论(0)
  • 2020-12-24 07:59

    I've created the following service to be able to get all route params as a ParamMap. The main idea behind it, is to recursively parse all the parameters from the child routes.

    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));
      }
    }
    

    Example Usage

    id;
    
    constructor(private paramMapService: ParamMapService) {
      this.paramMapService.paramMap.subscribe(paramMap => {
        this.id = paramMap.get('id');
      });
    }
    

    Note

    ES6 Map is being used in the service. To support older browsers, do one of the following:

    • Uncomment the import 'core-js/es6/map'; line in polyfills.ts, or
    • Convert all Map occurrences to a simple object.
    0 讨论(0)
  • 2020-12-24 08:00

    Angular 5:

    import { combineLatest } from 'rxjs/observable/combineLatest';
    
    
    
     constructor(
        private activatedRoute: ActivatedRoute
      ) {
        combineLatest(
          this.activatedRoute.data,
          this.activatedRoute.params
        ).subscribe(([{from}, params]) => {
          this.params.from = from;
          this.params.id = params['id'];
          this.loadData();
        });
      }
    
    0 讨论(0)
  • 2020-12-24 08:08

    As of Angular 5.2, you can do Router configuration to inherit all params to child states. See this commit if interested in the gory details, but here's how it's working for me:

    Wherever you have your call to RouterModule.forRoot(), include a configuration object with the inheritance strategy set to always (default is emptyOnly):

    import {RouterModule, ExtraOptions} from "@angular/router";
    
    export const routingConfiguration: ExtraOptions = {
      paramsInheritanceStrategy: 'always'
    };
    
    export const Routing = RouterModule.forRoot(routes, routingConfiguration);
    

    Now when you're in a child component looking at a ActivatedRoute, ancestors' params appear there (e.g. activatedRoute.params) rather than something messy like activatedRoute.parent.parent.parent.params. You could access the value directly (e.g. activatedRoute.params.value.userId) or subscribe via activatedRoute.params.subscribe(...).

    0 讨论(0)
  • 2020-12-24 08:13
    constructor(private route: ActivatedRoute) {}
    
    data$ = of(this.route).pipe(
        expand(route => of(route['parent'])),
        takeWhile(route => !!route['parent']),
        pluck('snapshot', 'data'),
        reduce(merge));
    

    Explanation:

    Calling expand here creates an observable for each route in the parent chain. Takewhile is used so that it stops recursing when route['parent'] returns null, or at the root route.

    Then, for all of those routes in the observable, pluck will map each to it's 'snapshot.data' property.

    Finally, reduce is being fed the merge function from lodash to combine all the data objects into one object. This stream aggregates all the data from the current route through the parent routes

    0 讨论(0)
  • 2020-12-24 08:17

    I got the first route param this way:

    console.log(this.route.snapshot.firstChild.params)

    0 讨论(0)
提交回复
热议问题