我正在寻找在我的AppComponent中检测路由变化。

然后,我将检查全局用户令牌,以查看用户是否已登录,以便在用户未登录时重定向该用户。


当前回答

对于Angular 7,应该这样写:

this.router.events。订阅((事件:事件)=> {})


具体示例如下:

import { Component } from '@angular/core'; 
import { Router, Event, NavigationStart, NavigationEnd, NavigationError } from '@angular/router';

@Component({
    selector: 'app-root',
    template: `<router-outlet></router-outlet>`
})
export class AppComponent {

    constructor(private router: Router) {

        this.router.events.subscribe((event: Event) => {
            if (event instanceof NavigationStart) {
                // Show loading indicator
            }

            if (event instanceof NavigationEnd) {
                // Hide loading indicator
            }

            if (event instanceof NavigationError) {
                // Hide loading indicator

                // Present error to user
                console.log(event.error);
            }
        });

   }
}

其他回答

在花了一些时间寻找解决方案后,我找到了Angular 13.1.1的两个更新的变通方案:

第一选择:

  constructor(private router: Router) {
    router.events.forEach((event) => {
      if (event instanceof NavigationStart) {
        // Your code
        // Use (event.url) to get URL that is being navigated
      }
    });
  }

第二个选项

routerSubscription:订阅| undefined; 构造函数(私有路由器:router) {} ngAfterViewInit(): void { 这一点。routerSubscription = this.router.events.subscribe((event) => { if(事件实例of NavigationEnd) { //你的代码 //使用(event.url)获取正在导航的URL } }); }

记得取消订阅销毁循环

 ngOnDestroy(): void {
    this.routerSubscription?.unsubscribe();
  }

还要根据您的情况注意是否更好地使用

事件实例的NavigationStart

or

事件实例的NavigationEnd

@Ludohen的回答很好,但如果你不想使用instanceof,请使用下面的方法

this.router.events.subscribe(event => {
  if(event.constructor.name === "NavigationStart") {
    // do something...
  }
});

通过这种方式,您可以检查当前事件名称作为字符串,如果事件发生,您可以执行您计划的函数要执行的操作。

以上大多数解决方案是正确的,但我面临的问题是这个发射多次'导航发射'事件。当我改变任何路由时,此事件被触发。所以hear是Angular 6的完整解决方案。

import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';    

export class FooComponent implements OnInit, OnDestroy {
   private _routerSub = Subscription.EMPTY;
   constructor(private router: Router){}

   ngOnInit(){
     this._routerSub = this.router.events
      .filter(event => event instanceof NavigationEnd)
      .subscribe((value) => {
         //do something with the value
     });
  }

  ngOnDestroy(){
   this._routerSub.unsubscribe();
  }
} 

在Angular 10中,你可以像下面这样做……

    import { Component, OnInit } from '@angular/core';
    import { Router, NavigationEnd } from '@angular/router';
    import { filter } from 'rxjs/operators';
    
    @Component({
      selector: 'app-my-class',
      templateUrl: './my-class.component.html',
      styleUrls: ['./my-class.component.scss']
    })
    export class MyClassComponent implements OnInit {
      constructor(private router: Router) {}
    
      ngOnInit(): void {
        this.router.events
        .pipe(filter(event => event instanceof NavigationEnd))  
        .subscribe((event: NavigationEnd) => {
          // code goes here...
        });
      }
    }

更清晰的方法是继承RouteAware并实现onNavigationEnd()方法。

它是一个名为@bespunky/angular-zen的库的一部分。

NPM install @bespunky/angular-zen 让你的AppComponent扩展RouteAware并添加一个onNavigationEnd()方法。

import { Component     } from '@angular/core';
import { NavigationEnd } from '@angular/router';
import { RouteAware    } from '@bespunky/angular-zen/router-x';

@Component({
    selector   : 'app-root',
    templateUrl: './app.component.html',
    styleUrls  : ['./app.component.css']
})
export class AppComponent extends RouteAware
{    
    protected onNavigationEnd(event: NavigationEnd): void
    {
        // Handle authentication...
    }
}

RouteAware还有其他好处,比如: ✨任何路由器事件都可以有处理程序方法(Angular支持的路由器事件)。 ✨使用这个。路由器访问路由器 ✨使用这个。访问激活路由的路由 ✨使用this.componentBus访问RouterOutletComponentBus服务