navigationend example change javascript angular typescript angular2-routing

javascript - example - router events angular 6



Angular 2 router oyente de eventos (6)

¿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 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 el estado, console.info () en el servicio no funciona.

¿Qué hice mal?


Los eventos del enrutador angular 2 tienen diferentes clases, y lo que se pasa a la suscripción desde el router.events Los router.events observables pueden ser NavigationEnd , NavigationCancel , NavigationError o NavigationStart . El que realmente activará una actualización de enrutamiento será NavigationEnd .

Me mantendría alejado del uso de instanceof o event.constructor.name porque después de la event.constructor.name los nombres de clase se alterarán, no funcionará correctamente.

En su lugar, puede usar la función isActive del enrutador, que se muestra aquí https://angular.io/docs/ts/latest/api/router/index/Router-class.html

this.routerEventSubscription = this._router.events.subscribe((event: any) => { if (this._router.isActive(events.url, false)) { // true if the url route is active } }


Para escuchar todos los cambios de estado, extienda el RouterOutlet predeterminado y agregue su propia lógica en los controladores ''activar'' y ''desactivar''.

import {Directive} from ''angular2/core''; import {Router, RouterOutlet, ComponentInstruction} from ''angular2/router''; @Directive({ selector: ''router-outlet'' }) export class MyOwnRouterOutlet extends RouterOutlet { ... activate() { console.log(''Hello from the new router outlet!''); } }

Copiado del ejemplo ''Enrutador personalizado'' aquí: https://auth0.com/blog/2016/01/25/angular-2-series-part-4-component-router-in-depth/


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 vago , pero recuerde que el nombre del constructor se puede cambiar fácilmente mientras la función aún funciona.

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


También puede filtrar eventos con filter() .

Pero no solo use filter(e => e is NavigationEnd)

Una solución mucho mejor es agregar un ''protector de tipo'' al 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 la sintaxis de mecanografía)
  • e instanceof NavigationEnd es el código de tiempo de ejecución real que verifica el tipo

Lo bueno de esto es que los operadores más abajo ''en la tubería'', como el map continuación ahora saben que el tipo es NavigationEnd , pero sin la protección 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.


en angular2, vaya al archivo "app.modules.ts" -> importaciones

RouterModule.forRoot( appRoutes, { enableTracing: true } )

en enableTracing true show routeEvents en la consola en enableTracing false hide routeEvents en la consola


nuevo enrutador

constructor(router:Router) { router.events.subscribe(event:Event => { if(event instanceof NavigationStart) { } // NavigationEnd // NavigationCancel // NavigationError // RoutesRecognized }); }

antiguo

Inyecte el enrutador y suscríbase a 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 se generará un error NavigationStart is not defined .

Ver también