首页 文章

如何检测Angular中的路由变化?

提问于
浏览
237

我希望在 AppComponent 中检测路线变化 .

此后,我将检查全局用户令牌以查看他是否已登录 . 然后,如果用户未登录,我可以重定向用户 .

15 回答

  • 12

    这里的答案对于router-deprecated是正确的 . 对于router的最新版本:

    this.router.changes.forEach(() => {
        // Do whatever in here
    });
    

    要么

    this.router.changes.subscribe(() => {
         // Do whatever in here
    });
    

    要查看两者之间的差异,请查看this SO question .

    Edit

    最新的你必须做的:

    this.router.events.subscribe(event: Event => {
        // Handle route change
    });
    
  • 0

    RxJS 6

    router.events.pipe(filter(event => event instanceof NavigationStart))
    

    感谢Peilonrayz(见下面的评论)

    new router >= RC.3

    import { Router, NavigationStart, NavigationEnd, NavigationError, NavigationCancel, RoutesRecognized } from '@angular/router';
    
    constructor(router:Router) {
      router.events.forEach((event) => {
        if(event instanceof NavigationStart) {
        }
        // NavigationEnd
        // NavigationCancel
        // NavigationError
        // RoutesRecognized
      });
    }
    

    您还可以按给定的事件进行过滤:

    import 'rxjs/add/operator/filter';
    
    constructor(router:Router) {
      router.events
        .filter(event => event instanceof NavigationStart)
        .subscribe((event:NavigationStart) => {
          // You only receive NavigationStart events
        });
    }
    

    使用pairwise operator获取上一个和当前事件也是一个不错的主意 . https://github.com/angular/angular/issues/11268#issuecomment-244601977

    import'rxjs / add / operator / pairwise';
    从'@ angular / router导入
    ;

    export class AppComponent {
    构造函数(私有路由器:路由器){
    this.router.events.pairwise() . subscribe((event)=> {
    的console.log(事件);
    });
    };
    }

  • 5

    @Ludohen 答案很棒,但如果您不想使用 instanceof 请使用以下内容

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

    通过这种方式,您可以将当前事件名称检查为字符串,如果事件发生,您可以执行您计划的功能 .

  • 235

    以下列方式捕获路线变化事件......

    import { Component, OnInit, Output, ViewChild } from "@angular/core";
    import { Router, NavigationStart, NavigationEnd, Event as NavigationEvent } from '@angular/router';
    
    @Component({
        selector: "my-app",
        templateUrl: "app/app.component.html",
        styleUrls: ["app/app.component.css"]
    })
    export class AppComponent {
    
        constructor(private cacheComponentObj: CacheComponent,
            private router: Router) {
    
            /*  Route event types
                NavigationEnd
                NavigationCancel
                NavigationError
                RoutesRecognized
            */
            router.events.forEach((event: NavigationEvent) => {
    
                //Before Navigation
                if (event instanceof NavigationStart) {
                    switch (event.url) {
                    case "/app/home":
                    {
                        //Do Work
                        break;
                    }
                    case "/app/About":
                    {
                        //Do Work
                        break;
                    }
                    }
                }
    
                //After Navigation
                if (event instanceof NavigationEnd) {
                    switch (event.url) {
                    case "/app/home":
                    {
                        //Do Work
                        break;
                    }
                    case "/app/About":
                    {
                        //Do Work
                        break;
                    }
                    }
                }
            });
        }
    }
    
  • 13

    Angular 6,如果你想 subscriberouter

    import { Router, NavigationEnd } from '@angular/router';
    
    import { filter } from 'rxjs/operators';
    
    constructor(
      private router: Router
    ) {
      router.events.pipe(
        filter(event => event instanceof NavigationEnd)  
      ).subscribe((event: NavigationEnd) => {
        console.log(event.url);
      });
    }
    
  • 31

    Angular 4.x及以上:

    这可以使用ActivatedRoute类的url属性实现,如下所示,

    this.activatedRoute.url.subscribe(url =>{
         console.log(url);
    });
    

    Note: 您需要从 angular/router 包导入并注入提供程序

    import { ActivatedRoute } from '@angular/router`
    

    constructor(private activatedRoute : ActivatedRoute){  }
    
  • 0

    RC 5之后我这样做了

    this.router.events
      .map( event => event instanceof NavigationStart )
      .subscribe( () => {
        // TODO
      } );
    
  • 1

    以下KIND的作品可能对您来说很棘手 .

    // in constructor of your app.ts with router and auth services injected
    router.subscribe(path => {
        if (!authService.isAuthorised(path)) //whatever your auth service needs
            router.navigate(['/Login']);
        });
    

    不幸的是,这会在路由过程中重定向,而不是我想要的 . 在重定向之前调用原始目标组件的 onActivate() .

    您可以在目标组件上使用 @CanActivate 装饰器,但这是a)非集中式,b)不会从注入的服务中受益 .

    如果有人能够在提交之前建议更好的集中授权方式,那将会很棒 . 我相信一定有更好的方法 .

    这是我当前的代码(如何更改它以侦听路由更改?):

    import {Component, View, bootstrap, bind, provide} from 'angular2/angular2';
    import {ROUTER_BINDINGS, RouterOutlet, RouteConfig, RouterLink, ROUTER_PROVIDERS, APP_BASE_HREF} from 'angular2/router';    
    import {Location, LocationStrategy, HashLocationStrategy} from 'angular2/router';
    
    import { Todo } from './components/todo/todo';
    import { About } from './components/about/about';
    
    @Component({
        selector: 'app'
    })
    
    @View({
        template: `
            <div class="container">
                <nav>
                    <ul>
                        <li><a [router-link]="['/Home']">Todo</a></li>
                        <li><a [router-link]="['/About']">About</a></li>
                    </ul>
                </nav>
                <router-outlet></router-outlet>
            </div>
        `,
        directives: [RouterOutlet, RouterLink]
    })
    
    @RouteConfig([
        { path: '/', redirectTo: '/home' },
        { path: '/home', component: Todo, as: 'Home' },
        { path: '/about', component: About, as: 'About' }
    ])
    
    class AppComponent {    
        constructor(location: Location){
            location.go('/');
        }    
    }    
    bootstrap(AppComponent, [ROUTER_PROVIDERS, provide(APP_BASE_HREF, {useValue: '/'})]);
    
  • 310

    只需对AppRoutingModule进行更改即可

    @NgModule({
    imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
      exports: [RouterModule]
    })
    
  • 0

    在Angular 2中,您可以 subscribe (Rx事件)到Router实例 . 所以你可以做的事情

    class MyClass {
      constructor(private router: Router) {
        router.subscribe((val) => /*whatever*/)
      }
    }
    

    Edit (自rc.1起)

    class MyClass {
      constructor(private router: Router) {
        router.changes.subscribe((val) => /*whatever*/)
      }
    }
    

    Edit 2 (自2.0.0起)

    另见:Router.events doc

    class MyClass {
      constructor(private router: Router) {
        router.events.subscribe((val) => {
            // see also 
            console.log(val instanceof NavigationEnd) 
        });
      }
    }
    
  • 15

    路由器3.0.0-beta.2应该是

    this.router.events.subscribe(path => {
      console.log('path = ', path);
    });
    
  • 1
    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);
                }
            });
    
       }
    }
    
  • 7

    在角度6和RxJS6中:

    import { filter, debounceTime } from 'rxjs/operators';
    
     this.router.events.pipe(
          filter((event) => event instanceof NavigationEnd),
          debounceTime(40000)
        ).subscribe(
          x => {
          console.log('val',x);
          this.router.navigate(['/']); /*Redirect to Home*/
    }
    )
    
  • 0

    我正在使用angular5应用程序,我面临同样的问题 . 当我浏览Angular文档时,他们提供了处理路由器事件的最佳解决方案 . 请查看以下文档 .

    • Angular中的路由器事件Route events in angular5

    • 但特别针对有问题的案例我们需要 NavigationEnd Event

    Navigation End Event Angular

    表示导航成功结束时触发的事件

    How to use this ?

    import { Component, OnInit } from '@angular/core';
    import { Router, ActivatedRouteSnapshot, NavigationEnd } from '@angular/router';
    @Component({
        selector: 'app-navbar',
        templateUrl: './navbar.component.html',
        styleUrls: ['./navbar.component.css']
    })
    export class NavbarComponent implements OnInit {
        constructor(private router: Router) { }
        ngOnInit(): void {
            //calls this method when navigation ends
            this.router.events.subscribe(event => {
                if (event instanceof NavigationEnd) {
                    //calls this stuff when navigation ends
                    console.log("Event generated");
                }
            });
        }
    }
    

    When to use this ?

    在我的情况下,我的应用程序为所有用户(例如用户,管理员)共享公共仪表板,但我需要根据用户类型显示和隐藏一些导航栏选项 .

    这就是为什么每当url更改时我需要调用服务方法,该方法根据响应返回登录的用户信息,我将进行进一步的操作 .

  • 4

    以上大多数解决方案都是正确的,但是我面临的问题就是多次发出“导出发射”事件 . 当我更改任何路线时,会触发此事件 . 所以听到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();
      }
    }
    

相关问题