Is there better way to get ancestor route params in Angular2?

前端 未结 2 352
伪装坚强ぢ
伪装坚强ぢ 2021-01-17 13:09

I need to get param from route which is not parent and not even grand-parent, it\'s simply somewhere above, along the path to root. I am aware of approaches like shown in An

相关标签:
2条回答
  • 2021-01-17 13:33

    I ran into the same problem and after finding this answer I created this function called getParams() that gets all the params of the parents and the current root.

    It combines all the params and reduces into a single map.

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { ServicosService } from '@service/core/servicos.service';
    import { ActivatedRoute } from '@angular/router';
    import { Observable } from 'rxjs/Observable';
    import { map, combineAll } from 'rxjs/operators';
    
    @Injectable()
    export abstract class HttpServiceRouted {
      constructor(
        protected http: HttpClient,
        protected servicos: ServicosService,
        protected route: ActivatedRoute
      ) {}
    
      getParams() {
        return Observable.from(this.route.pathFromRoot.concat(this.route)).pipe(
          map(route => route.params),
          combineAll(),
          map((params: any[]) =>
            params.reduce(
              // tslint:disable-next-line:no-shadowed-variable
              (map: Map<string, string>, obj) => {
                Object.keys(obj).forEach(key => {
                  map.set(key, obj[key]);
                });
                return map;
              },
              new Map<string, string>()
            )
          )
        );
      }
    }
    

    Usage:

    this.getParams().subscribe((params: ParamMap) => {
      const id = params.get('id');
    });
    
    0 讨论(0)
  • 2021-01-17 13:49

    Generally, I think your approach does make sense.

    I do not know the exact background for the code, but it does feel like a child component wanting to know lots about parent instance data, and I would agree with @Aravind's comment that this is likely best dealt with in global state management solutions such as redux or ngrx. That being said, if this is all you would need it for, I understand you would not want to introduce that level of complexity.

    I would only make minor adjustments to your rxchain so it is more readable.

    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute, Params } from '@angular/router';
    import { Observable } from 'rxjs/Observable';
    
    import { Model } from './model';
    import { ModelService } from './model.service';
    
    @Component({
        ...
    })
    export class ModelsComponent implements OnInit {
        models: Model[];
    
        constructor(
            private route: ActivatedRoute,
            private modelService: ModelService) { }
    
        ngOnInit() {
            const paramsArr = this.route.pathFromRoot;
    
            Observable.from(paramsArr)
                .map(route => route.params)
                .filter(params => params.containerId)
                .switchMap(containerId => this.modelService.getAllBelongingTo(containerId))
                .subscribe(
                    (models: Model[]) => {
                        // yay! we got sth
                        this.models = models;
                    },
                    error => {
                        // handle big nono
                    }
                );
        }
    }
    

    Note however this implementation will only set this.models when there is a containerId as a parameter to a parent

    EDIT 1: Fixed typos

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