Come rilevare un cambio di rotta in Angolare?

Sto cercando di rilevare un cambio di rotta nel mio AppComponent .

Successivamente controllerò il token dell’utente globale per vedere se è loggato. Quindi posso redirect l’utente se non è loggato.

In Angular 2 è ansible subscribe (evento Rx) a un’istanza del router. Quindi puoi fare cose come

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

Modifica (da rc.1)

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

Modifica 2 (dalla 2.0.0)

vedi anche: Router.events doc

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

nuovo 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 }); } 

Puoi anche filtrare in base all’evento specificato:

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

Anche l’utilizzo dell’operatore pairwise per ottenere l’evento precedente e corrente è una buona idea. https://github.com/angular/angular/issues/11268#issuecomment-244601977

 import 'rxjs/add/operator/pairwise'; import { Router } from '@angular/router; export class AppComponent { constructor(private router: Router) { this.router.events.pairwise().subscribe((event) => { console.log(event); }); }; } 

Angolare 4.xe versioni successive:

Questo può essere ottenuto usando la proprietà url della class ActivatedRoute come sotto,

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

Nota: è necessario importare e iniettare il provider dal pacchetto angular/router

 import { ActivatedRoute } from '@angular/router` 

e

 constructor(private activatedRoute : ActivatedRoute){ } 

Il router 3.0.0-beta.2 dovrebbe essere

 this.router.events.subscribe(path => { console.log('path = ', path); }); 

Le risposte qui sono corrette per il router-deprecated . Per l’ultima versione del router :

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

o

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

Per vedere la differenza tra i due, si prega di consultare questa domanda SO .

modificare

Per l’ultimo devi fare:

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

In angular 6 e 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*/ } ) 

Cattura gli eventi di cambio percorso nel modo seguente …

 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; } } } }); } } 

La risposta @Ludohen è ottima, ma nel caso in cui non si desideri utilizzare instanceof utilizzare quanto segue

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

in questo modo puoi controllare il nome dell’evento corrente come una stringa e se l’evento si verifica, puoi fare ciò che hai pianificato per la tua funzione.

Il seguente TIPO di opere e può fare il difficile per te.

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

Sfortunatamente questo reindirizza più avanti nel processo di routing di quanto mi piacerebbe. L’ onActivate() del componente di destinazione originale viene chiamato prima del reindirizzamento.

C’è un decoratore @CanActivate che puoi utilizzare sul componente target, ma questo è a) non centralizzato e b) non beneficia dei servizi iniettati.

Sarebbe bello se qualcuno potesse suggerire un modo migliore di autorizzare centralmente un percorso prima che fosse commesso. Sono sicuro che ci deve essere un modo migliore.

Questo è il mio codice attuale (come dovrei cambiarlo per ascoltare la modifica del percorso?):

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

Lo faccio da quando RC 5

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