Angular 2 get routeParams in a service

前端 未结 6 472
情话喂你
情话喂你 2021-01-02 05:58

I want to shift the logic from component to service. But I found out that I can\'t get the routeParams in a service.

My component looks like

import {         


        
相关标签:
6条回答
  • 2021-01-02 06:23

    Acording to this you have to traverse down the route tree and get the data from the route at the bottom of the tree.

    @Injectable()
    export class MyService{
    
      constructor(private router:Router,private route:ActivatedRoute){   
       this.router.events
        .filter(event => event instanceof NavigationEnd)
         .subscribe((event) => {
             let r=this.route;
             while (r.firstChild) {
                r = r.firstChild
            }
             //we need to use first, or we will end up having
             //an increasing number of subscriptions after each route change.   
             r.params.first().subscribe(params=>{                
               // Now you can use the params to do whatever you want
             });             
    
    
        });            
      }
    }
    
    0 讨论(0)
  • 2021-01-02 06:29

    Something like this works for me in Angular 8:

    export class TheService {
    
      params$: Observable<any>;
    
      constructor(private router: Router) {
        this.params$ = this.router.events.pipe(
          filter(event => event instanceof NavigationEnd),
          map(event => this.getLeafRoute(this.router.routerState.root).snapshot.params)
        );
      }
    
      private getLeafRoute(route: ActivatedRoute): ActivatedRoute {
        if (route === null) return null; //or throw ?
        while (route.firstChild) route = route.firstChild;
        return route;
      }
    }
    
    0 讨论(0)
  • 2021-01-02 06:35

    the problem is the

    return this.route.params;
    

    the route params are not ready at that moment -> observables -> asynchronicity

    0 讨论(0)
  • 2021-01-02 06:35

    I worked with @juansb827 answer and I got it to work when I got rid of the event filter and went directly for the traversal of that ActiveRoute. It worked for me. It's possible that, in my case, that event already happened by the time the service was being executed because my traversal was in a different method in my service.

    0 讨论(0)
  • 2021-01-02 06:37

    I like managing state through the URL, and built a simple state service that observes route navigation end events and exposes observable endpoints for each route parameter.

    import { Injectable } from '@angular/core';
    import {NavigationEnd, Router} from '@angular/router';
    import {BehaviorSubject} from 'rxjs';
    import { filter } from 'rxjs/operators';
    
    @Injectable({
      providedIn: 'root'
    })
    export class DigStateService {
      public state = {};
    
      constructor(private router: Router) {
        this.router.events.pipe(
          filter(event => event instanceof NavigationEnd)
        ).subscribe(() => {
          let route = this.router.routerState.snapshot.root;
          do {
            const params = route.params;
            const keys = Object.keys(params);
            if (keys.length > 0) {
              keys.forEach(key => {
                const val = params[key];
                if (this.state[key]) {
                  this.state[key].next(val);
                } else {
                  this.state[key] = new BehaviorSubject(val);
                }
              });
            }
            route = route.firstChild;
          } while (route);
        });
      }
    
      param(key) {
        // if this key does not exist yet create it so its observable when it is set
        if (! this.state[key]) {
          this.state[key] = new BehaviorSubject(null);
        }
        return this.state[key];
      }
    }

    Then you can use this service to observe individual route params from anywhere in the tree:

    stateService.param('project').subscribe(projectId => {
      console.log('project ' + projectId);
    });

    0 讨论(0)
  • 2021-01-02 06:40

    We can pass ActivatedRoute to service from component. Then subscribe to route.params in service class

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