How to detect a route change in Angular?

前端 未结 22 1512
花落未央
花落未央 2020-11-22 04:40

I am looking to detect a route change in my AppComponent.

Thereafter I will check the global user token to see if he is logged in. Then I can redirect t

相关标签:
22条回答
  • 2020-11-22 05:19

    The answers here are correct for router-deprecated. For the latest version of router:

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

    or

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

    To see the difference between the two, please check out this SO question.

    Edit

    For the latest you must do:

    this.router.events.subscribe(event: Event => {
        // Handle route change
    });
    
    0 讨论(0)
  • 2020-11-22 05:23

    In Angular 2 you can subscribe (Rx event) to a Router instance. So you can do things like

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

    Edit (since rc.1)

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

    Edit 2 (since 2.0.0)

    see also : Router.events doc

    class MyClass {
      constructor(private router: Router) {
        router.events.subscribe((val) => {
            // see also 
            console.log(val instanceof NavigationEnd) 
        });
      }
    }
    
    0 讨论(0)
  • 2020-11-22 05:24

    In Angular 10, you can do something like the following...

        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...
            });
          }
        }
    
    0 讨论(0)
  • 2020-11-22 05:26

    @Ludohen answer is great, but in case you don't want to use instanceof use the following

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

    with this way you can check the current event name as a string and if the event occurred you can do what you planned your function to do.

    0 讨论(0)
  • 2020-11-22 05:27

    For Angular 7 someone should write like:

    this.router.events.subscribe((event: Event) => {})


    A detailed example can be as follows:

    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);
                }
            });
    
       }
    }
    
    0 讨论(0)
  • 2020-11-22 05:27

    The following KIND of works and may do the tricky for you.

    // 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']);
        });
    

    Unfortunately this redirects later in the routing process than I'd like. The onActivate() of the original target component is called before the redirect.

    There is a @CanActivate decorator you can use on the target component but this is a) not centralised and b) does not benefit from injected services.

    It would be great if anyone can suggest a better way of centrally authorising a route before it is committed. I'm sure there must be a better way.

    This is my current code (How would I change it to listen to the route change?):

    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: '/'})]);
    
    0 讨论(0)
提交回复
热议问题