¿Cómo detectar un cambio de ruta en Angular?

Estoy buscando detectar un cambio de ruta en mi AppComponent .

A partir de entonces comprobaré el token de usuario global para ver si está conectado. Luego puedo redirigir al usuario si no está conectado.

En Angular 2 puede subscribe (evento Rx) a una instancia de enrutador. Entonces puedes hacer cosas como

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

Editar (desde rc.1)

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

Editar 2 (desde 2.0.0)

ver también: Router.events doc

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

nuevo enrutador> = 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 }); } 

También puede filtrar por el evento dado:

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

Usar el operador pairwise para obtener el evento anterior y actual también es una buena 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); }); }; } 

Angular 4.xy superior:

Esto se puede lograr usando la propiedad url de la clase ActivatedRoute como se muestra a continuación,

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

Nota: que necesita importar e inyectar el proveedor del paquete angular/router

 import { ActivatedRoute } from '@angular/router` 

y

 constructor(private activatedRoute : ActivatedRoute){ } 

Router 3.0.0-beta.2 debe ser

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

Las respuestas aquí son correctas para el router-deprecated . Para la última versión del router :

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

o

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

Para ver la diferencia entre los dos, echa un vistazo a esta pregunta SO .

Editar

Para lo último debes hacerlo:

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

En angular 6 y 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*/ } ) 

Capture eventos de cambio de ruta de la siguiente manera …

 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 respuesta de @Ludohen es genial, pero en caso de que no quiera usarla instanceof use la siguiente

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

de esta forma puede verificar el nombre del evento actual como una cadena y, si el evento ocurrió, puede hacer lo que planeó que haga su función.

El siguiente TIPO de obras puede ser complicado para ti.

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

Desafortunadamente, esto redirige más tarde del proceso de enrutamiento del que me gustaría. El onActivate() del componente objective original se llama antes de la redirección.

Hay un decorador @CanActivate que puede usar en el componente de destino, pero esto es a) no centralizado yb) no se beneficia de los servicios inyectados.

Sería genial si alguien puede sugerir una mejor manera de autorizar centralmente una ruta antes de que se cometa. Estoy seguro de que debe haber una mejor manera.

Este es mi código actual (¿Cómo lo cambiaría para escuchar el cambio de ruta?):

 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 hago así desde RC 5

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