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