Comment détecter un changement d'itinéraire Angulaire?
je cherche à détecter un changement de route dans mon AppComponent
.
par la suite, je vérifierai le token utilisateur global pour voir s'il est connecté. Ensuite, je peux rediriger l'utilisateur si il n'est pas connecté.
11 réponses
en angle 2 Vous pouvez subscribe
(événement Rx) à une instance de routeur.
Donc vous pouvez faire des choses comme
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
Modifier (depuis la rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
Edit 2 (depuis la version 2.0.0)
Voir Aussi: Routeur.Evénements doc
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
nouveau routeur >= 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
});
}
Vous pouvez également filtrer par l'événement:
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
utiliser le pairwise
opérateur pour obtenir l'événement précédent et actuel est également une bonne idée. 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); }); }; }
angle 4.x et au-dessus:
cela peut être réalisé en utilisant la propriété url de ActivatedRoute class as below,
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
Note:
Que vous devez importer et injecter le fournisseur de angular/router
paquet
import { ActivatedRoute } from '@angular/router`
et
constructor(private activatedRoute : ActivatedRoute){ }
Routeur 3.0.0-beta.2 devrait être
this.router.events.subscribe(path => {
console.log('path = ', path);
});
les réponses ici sont correctes pour router-deprecated
. Pour la dernière version de router
:
this.router.changes.forEach(() => {
// Do whatever in here
});
ou
this.router.changes.subscribe(() => {
// Do whatever in here
});
pour voir la différence entre les deux, veuillez cocher this SO question .
Modifier
pour le dernier vous devez faire:
this.router.events.subscribe(event: Event => {
// Handle route change
});
en angle 6 et 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*/
}
)
capturer les changements de route de la manière suivante...
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;
}
}
}
});
}
}
@Ludohen la réponse est grande, mais dans le cas où vous ne voulez pas utiliser instanceof
utilisez la suivante
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
avec cette façon, vous pouvez vérifier le nom de l'événement comme une chaîne de caractères et si l'événement s'est produit, vous pouvez faire ce que vous avez prévu votre fonction pour le faire.
le genre de travaux suivants et peut faire le délicat pour vous.
// 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']);
});
malheureusement cela redirige plus tard dans le processus de routage que je voudrais. Le onActivate()
du composant cible original est appelé avant la redirection.
il y a un @CanActivate
décorateur que vous pouvez utiliser sur le composant cible, mais il s'agit a) pas centralisé et b) ne bénéficie pas de services injectés.
ce serait génial si n'importe qui peut suggérer une meilleure façon d'autoriser centralement une route avant qu'elle ne soit engagée. Je suis sûr qu'il doit y avoir une meilleure façon.
C'est mon code actuel (comment le changer pour écouter le changement de route?):
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: '/'})]);
je fais comme ça depuis RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
je travaille avec angular5 application et je fais face à la même question . quand je passe en revue la Documentation angulaire ils fournissent la meilleure solution pour manipuler les événements de routeur.vérifiez la documentation suivante.
-
événements de routeur en angle les événements d'Itinéraire en angular5
-
mais spécifiquement pour le cas de fournir en question nous avons besoin événement NavigationEnd
représente un événement déclenché lorsqu'une navigation se termine avec succès
comment utiliser ceci ?
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");
}
});
}
}
quand utiliser ceci ?
dans mon cas, mon application partagent un tableau de bord commun pour tous les utilisateurs tels que: utilisateurs, administrateurs, mais j'ai besoin d'afficher et de cacher certaines options navbar selon les types d'utilisateurs.
C'est pourquoi chaque fois que l'url change, je dois appeler la méthode de service qui renvoie les informations d'utilisateur enregistrées selon la réponse, je vais aller pour des opérations ultérieures.