Angular 2 - Check current active route “name”

后端 未结 6 1625
说谎
说谎 2020-12-24 09:36

I am having an Angular 2 application with several nested children view. But it will be displayed on the same page though several router-outlet.



        
6条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-24 10:12

    • I would create a simple service that tracks the active state.
    • This service can be injected where needed to get or set the active state.
    • You are already using Resolvers, so you could set the state identifier in there.

    Create a Service called ActiveState:

    import {Injectable} from "@angular/core";
    import {Observable} from "rxjs";
    
    @Injectable()
    export class ActiveState {
    
      public current : Observable;
      private observer : any;
    
      constructor()
      {
        // Create an observable (it can be subscribed to)
        this.current = new Observable(observer => {
          this.observer = observer;
          observer.next('Unknown'); // The default unknown state
        });
      }
    
      setActive(name : string) : void
      {
        this.observer.next(name);
      }
    }
    

    In your resolvers such as PointListResolve ... TaskListResolve etc.

    import {Resolve, ActivatedRouteSnapshot} from "@angular/router";
    import {Injectable} from "@angular/core";
    import {Observable} from "rxjs";
    import {ActiveState} from "services/ActiveState.service"; 
    
    @Injectable()
    export class PointListResolver implements Resolve {
    
      // Inject the ActiveState in your constructor
      constructor(private state : ActiveState) {}
    
      resolve(route: ActivatedRouteSnapshot): Observable {
        // Set the active state name
        this.state.setActive("Point"); // We are here: /queue/:date/:offset/:type/:bundleId/:pointId
    
        // Do your regular resolve functionality (if you don't need to resolve, this blank resolver of an empty object will work)
        // ...
        return Observable.of({});
      }
    }
    

    So in the other resolvers update the this.state.setActive("") value as required.


    Then to determine which state you are in, inject ActiveState where you want to use the current state, such as in a @Component, i.e.

    import {Component, OnDestroy} from '@angular/core';
    import {ActiveState} from "services/ActiveState.service";
    
    @Component({
      selector: 'my-current-state-component',
      template: `The current state is: {{stateName}}`,
    })
    export class MyCurrentStateComponent implements OnDestroy {
    
      public stateName : string;
      private sub : Subscription;
    
      // Inject in ActiveState
      constructor(private state : ActiveState)
      {
        // Subscribe to the current State
        this.sub = state.current.subscribe(name => {
          this.stateName = name;
    
          // Other logic to perform when the active route name changes
          ...
        });
      }
    
      ngOnDestroy()
      {
         this.sub.unsubscribe();
      }
    }
    

    Notes:

    • Don't forget to register your ActiveState service as a Provider in:

      @NgModule({
        ...
        providers:[ActiveState]
        ...
      })
      export class AppModule { }
      
    • Simpler - Non-Observable Version I've used an Observable so changes to the active state can be subscribed to, but this could be simplified to just be a string if you don't want that functionality:

      import {Injectable} from "@angular/core";
      
      @Injectable()
      export class ActiveState {
      
        public current : string;
      
        setActive(name : string) : void
        {
          this.current = name;
        }
      
        is(name : string) : boolean
        {
          return name == this.current;
        }
      }
      

      Then when you inject state : ActiveState you can simple test the value state.is("Point")

    I hope that's useful.

提交回复
热议问题