¿Cómo escuchar el cambio de estado en el enrutador Angular 2?
En Angular 1.x utilicé este evento:
$rootScope.$on('$stateChangeStart', function(event,toState,toParams,fromState,fromParams, options){ ... })Entonces, si uso este eventlistener en Angular 2:
window.addEventListener("hashchange", () => {return console.log('ok')}, false);no se devuelve 'ok', luego cambia el estado de JS, solo luego se ejecuta la función history.back() del navegador.
Utilice la función router.subscribe() como servicio:
import {Injectable} from 'angular2/core'; import {Router} from 'angular2/router'; @Injectable() export class SubscribeService { constructor (private _router: Router) { this._router.subscribe(val => { console.info(val, '<-- subscribe func'); }) } }Inyecte el servicio en el componente que se inicia en el enrutamiento:
import {Component} from 'angular2/core'; import {Router} from 'angular2/router'; @Component({ selector: 'main', templateUrl: '../templates/main.html', providers: [SubscribeService] }) export class MainComponent { constructor (private subscribeService: SubscribeService) {} }Inyecto este servicio en otros componentes como en este ejemplo. Luego cambio de estado, console.info() en servicio no funciona.
¿Qué hice mal?
enrutador nuevo
constructor(router:Router) { router.events.subscribe(event:Event => { if(event instanceof NavigationStart) { } // NavigationEnd // NavigationCancel // NavigationError // RoutesRecognized }); }antiguo
Inyecte el enrutador y suscríbase a los eventos de cambio de ruta
import {Router} from 'angular2/router'; class MyComponent { constructor(router:Router) { router.subscribe(...) } }NOTA
Para el nuevo enrutador, no olvide importar NavigationStart desde el módulo del router
import { Router, NavigationStart } from '@angular/router'; porque si no lo importa, instanceof no funcionará y aparecerá un error NavigationStart is not defined .
Ver también
También puede filtrar eventos con filter() .
Pero no use solo filter(e => e is NavigationEnd)
Una solución mucho mejor es agregar un 'protector de tipo' a filter() como este:
filter((e): e is NavigationEnd => e instanceof NavigationEnd),Contiene dos cosas:
e is NavigationEnd esta es la afirmación para la que está definiendo una función (esta es una sintaxis mecanografiada y está completamente eliminada del javascript transpilado)e instanceof NavigationEnd este es el código de tiempo de ejecución real que comprueba el tipo Lo bueno de esto es que los operadores más abajo en 'la tubería', como el map a continuación, ahora saben que el tipo es NavigationEnd , pero sin el protector de tipo tendrías un tipo Event .
Si solo necesita verificar un tipo de evento, esta es la forma más limpia de hacerlo. Esto también parece ser necesario en modo estricto para evitar errores del compilador.
Puede usar instanceof como respondió @GünterZöchbauer
this.router.events.subscribe(event => { if(event instanceof NavigationStart) { // do something... } }o puede usar un enfoque más perezoso , ¡pero recuerde que el nombre del constructor se puede cambiar fácilmente mientras la función aún está funcionando!
this.router.events.subscribe(event => { if(event.constructor.name === "NavigationStart") { // do something... } });