route page navigationend change based angular

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



router angular navigationend (16)

Estoy buscando detectar un cambio de ruta en mi AppComponent .

Posteriormente, comprobaré el token de usuario global para ver si ha iniciado sesión. Luego, puedo redirigir al usuario si no ha iniciado sesión.


Capture eventos de cambio de ruta de la siguiente manera ...

import {NavigationEnd, NavigationStart, Router} from ''@angular/router''; constructor(private router: Router) { router.events.subscribe( (event) => { if (event instanceof NavigationStart) // start loading pages if (event instanceof NavigationEnd) { // end of loading paegs } }); }


Angular 4.xy superior:

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

import { ActivatedRoute } from ''@angular/router`

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

constructor(private activatedRoute : ActivatedRoute){ }

y

import { Router, NavigationEnd } from ''@angular/router''; import { filter } from ''rxjs/operators''; constructor( private router: Router ) { router.events.pipe( filter(event => event instanceof NavigationEnd) ).subscribe((event: NavigationEnd) => { console.log(event.url); }); }


El siguiente TIPO de trabajos y puede hacer el truco para usted.

// 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 en el proceso de enrutamiento de lo que me gustaría. El onActivate() del componente de destino original se llama antes de la redirección.

Hay un decorador @CanActivate que puede usar en el componente de destino, pero este 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 comprometa. 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: ` <div class="container"> <nav> <ul> <li><a [router-link]="[''/Home'']">Todo</a></li> <li><a [router-link]="[''/About'']">About</a></li> </ul> </nav> <router-outlet></router-outlet> </div> `, 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: ''/''})]);


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*/) } }

Edición 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) }); } }


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*/ } )


En el componente, es posible que desee probar esto:

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


Estoy trabajando con la aplicación angular5 y estoy enfrentando el mismo problema. Cuando reviso la documentación angular, proporcionan la mejor solución para manejar los eventos del enrutador. Verifique la siguiente documentación.

Representa un evento desencadenado cuando una navegación finaliza correctamente

Como usar esto ?

import { Subscription } from ''rxjs/Subscription''; import ''rxjs/add/operator/do''; import ''rxjs/add/operator/filter''; export class FooComponent implements OnInit, OnDestroy { private _routerSub = Subscription.EMPTY; constructor(private router: Router){} ngOnInit(){ this._routerSub = this.router.events .filter(event => event instanceof NavigationEnd) .subscribe((value) => { //do something with the value }); } ngOnDestroy(){ this._routerSub.unsubscribe(); } }

¿Cuándo usar esto?

En mi caso, mi aplicación comparte un tablero común para todos los usuarios, como usuarios, administradores, pero necesito mostrar y ocultar algunas opciones de la barra de navegación según los tipos de usuarios.

Es por eso que cada vez que cambia la URL, necesito llamar al método de servicio que devuelve la información de usuario registrada según la respuesta, iré para más operaciones.


Las respuestas aquí son correctas para 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, consulte esta pregunta SO .

Editar

Para lo último debes hacer:

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


Lo hago así desde RC 5

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


Para Angular 7, alguien debería escribir como:

this.router.events.subscribe((event: Event) => {})

Un ejemplo detallado puede ser el siguiente:

import { Component } from ''@angular/core''; import { Router, Event, NavigationStart, NavigationEnd, NavigationError } from ''@angular/router''; @Component({ selector: ''app-root'', template: `<router-outlet></router-outlet>` }) export class AppComponent { constructor(private router: Router) { this.router.events.subscribe((event: Event) => { if (event instanceof NavigationStart) { // Show loading indicator } if (event instanceof NavigationEnd) { // Hide loading indicator } if (event instanceof NavigationError) { // Hide loading indicator // Present error to user console.log(event.error); } }); } }


Router 3.0.0-beta.2 debería ser

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


Simplemente haga cambios en AppRoutingModule como

@NgModule({ imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: ''enabled'' })], exports: [RouterModule] })


arriba, la mayoría de las soluciones son correctas, pero estoy enfrentando un problema que emite varias veces el evento ''Navigation emit''. Cuando cambié alguna ruta, este evento se activa. Entonces escuchar es la solución completa para Angular 6.

import { Component, OnInit } from ''@angular/core''; import { Router, ActivatedRouteSnapshot, NavigationEnd } from ''@angular/router''; @Component({ selector: ''app-navbar'', templateUrl: ''./navbar.component.html'', styleUrls: [''./navbar.component.css''] }) export class NavbarComponent implements OnInit { constructor(private router: Router) { } ngOnInit(): void { //calls this method when navigation ends this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { //calls this stuff when navigation ends console.log("Event generated"); } }); } }


Angular 7 , si desea subscribe al router

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


La respuesta de @Ludohen es excelente, pero en caso de que no desee utilizar la instanceof use lo siguiente

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

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


RxJS 6

router.events.pipe(filter(event => event instanceof NavigationStart))

Gracias a Peilonrayz (ver comentarios a continuación)

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