Cómo detectar un cambio de ruta en Angular?
Estoy buscando detectar un cambio de ruta en mi AppComponent
.
A partir de entonces voy a comprobar el token de usuario global para ver si está conectado. Entonces puedo redirigir al usuario si no está conectado.
11 answers
En Angular 2 puede subscribe
(evento Rx) a una instancia de enrutador.
Así que 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)
Véase también : Router.eventos doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-13 14:31:55
Nuevo router > = 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
});
}
Usando el pairwise
operator 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); }); }; }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-22 12:54:39
Angular 4.x y superiores :
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 desde angular/router
paquete
import { ActivatedRoute } from '@angular/router`
Y
constructor(private activatedRoute : ActivatedRoute){ }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-31 07:47:37
Router 3.0.0-beta.2 debe ser
this.router.events.subscribe(path => {
console.log('path = ', path);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-06 16:52:40
Las respuestas aquí son correctas para router-deprecated
. Para la última versión de 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, por favor echa un vistazo esta pregunta SO.
Editar
Para la última debe hacer:
this.router.events.subscribe(event: Event => {
// Handle route change
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:48
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*/
}
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-15 13:12:33
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;
}
}
}
});
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-20 09:36:43
@Ludohen la respuesta es genial, pero en caso de que no quieras usar instanceof
usa 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 el evento ocurrió, puede hacer lo que planeó hacer su función.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-05 10:25:59
El siguiente TIPO de obras y puede hacer el difícil 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 esto a) no es centralizado y b) 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 sea comprometido. 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: '/'})]);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-05 10:30:07
Lo hago así desde RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 13:14:30
Estoy trabajando con la aplicación angular5 y me enfrento al mismo problema . cuando paso por la documentación de Angular, proporcionan la mejor solución para el manejo de eventos de enrutador.compruebe la siguiente documentación.
Eventos de Router en Angular eventos de Ruta en angular5
-
Pero específicamente para el caso proporcionar en cuestión necesitamos Evento NavigationEnd
Representa un evento activado cuando una navegación termina correctamente
Cómo usar esto ?
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");
}
});
}
}
¿Cuándo usar esto ?
En mi caso , mi aplicación comparte un panel de control 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 usuario.
Es por eso que cada vez que cambia la url, necesito llamar al método de servicio que devuelve la información del usuario registrada según la respuesta, iré a realizar más operaciones.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-06 10:41:37