Réponses:
Dans Angular 2, vous pouvez subscribe
(événement Rx) vers une instance de routeur. Vous pouvez donc faire des choses comme
class MyClass {
constructor(private router: Router) {
router.subscribe((val) => /*whatever*/)
}
}
Modifier (depuis rc.1)
class MyClass {
constructor(private router: Router) {
router.changes.subscribe((val) => /*whatever*/)
}
}
Edit 2 (depuis 2.0.0)
voir aussi: doc Router.events
class MyClass {
constructor(private router: Router) {
router.events.subscribe((val) => {
// see also
console.log(val instanceof NavigationEnd)
});
}
}
filter
opérateur RxJS . router.events.pipe(filter(e => e instanceof NavigationEnd).subscribe((e) => { ... }
RxJS 6
router.events.pipe(filter(event => event instanceof NavigationStart))
Merci à Peilonrayz (voir les commentaires ci-dessous)
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 donné:
import 'rxjs/add/operator/filter';
constructor(router:Router) {
router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event:NavigationStart) => {
// You only receive NavigationStart events
});
}
L'utilisation de l' 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); }); }; }
Argument of type '(event: Event) => void' is not assignable to parameter of type
Argument of type '(event: Event) => void' is not assignable to parameter of type
erreur est due au fait que dans votre extrait de filtre, vous vous abonnez à un objet de type Event au lieu de NavigationEvent.
Pour Angular 7, quelqu'un devrait écrire comme:
this.router.events.subscribe((event: Event) => {})
Un exemple détaillé peut être le suivant:
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);
}
});
}
}
Angulaire 7 , si vous voulez subscribe
larouter
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);
});
}
Angulaire 4.x et supérieur:
Ceci peut être réalisé en utilisant la propriété url de la classe ActivatedRoute comme ci-dessous,
this.activatedRoute.url.subscribe(url =>{
console.log(url);
});
Remarque:
que vous devez importer et injecter le fournisseur à partir du angular/router
package
import { ActivatedRoute } from '@angular/router`
et
constructor(private activatedRoute : ActivatedRoute){ }
Le routeur 3.0.0-beta.2 devrait être
this.router.events.subscribe(path => {
console.log('path = ', path);
});
En angulaire 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*/
}
)
import {Router, NavigationEnd} from "@angular/router"
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 consulter cette question SO .
Éditer
Pour les dernières, vous devez faire:
this.router.events.subscribe(event: Event => {
// Handle route change
});
router
a été mis à jour à nouveau (je n'ai pas encore mis à jour ma réponse), donc je ne sais pas comment c'est pour la dernière. Pour ce dont router
j'ai parlé, vous ne pouviez pas. @akn
Dans Angular 8, vous devriez faire comme this.router.events.subscribe((event: Event) => {})
Exemple:
import { Component } from '@angular/core';
import { Router, Event } from '@angular/router';
import { NavigationStart, NavigationError, NavigationEnd } from '@angular/router';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {
constructor(private router: Router) {
//Router subscriber
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
//do something on start activity
}
if (event instanceof NavigationError) {
// Handle error
console.error(event.error);
}
if (event instanceof NavigationEnd) {
//do something on end activity
}
});
}
}
Dans le composant, vous pouvez essayer ceci:
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
}
});
}
Capturez les événements de changement d'itinéraire 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;
}
}
}
});
}
}
La localisation fonctionne ...
import {Component, OnInit} from '@angular/core';
import {Location} from '@angular/common';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
constructor(private location: Location) {
this.location.onUrlChange(x => this.urlChange(x));
}
ngOnInit(): void {}
urlChange(x) {
console.log(x);
}
}
au-dessus de la plupart des solutions correctes, mais je suis confronté à un problème qui émet plusieurs fois l'événement "Emission de navigation". Hear est donc la solution complète pour Angular 6.
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();
}
}
@Ludohen est une bonne réponse, mais au cas où vous ne voudriez pas utiliser, instanceof
utilisez ce qui suit
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
de cette façon, vous pouvez vérifier le nom de l'événement actuel sous forme de chaîne et si l'événement s'est produit, vous pouvez faire ce que vous avez prévu de faire votre fonction.
Event
type provoque une erreur dans Atom c'est pourquoi je ne l'ai pas utilisé
instanceOf
pour que votre exemple fonctionne également dans le code de production. if(event instanceOf NavigationStart) {
if(event instanceof NavigationStart)
Je travaille avec l'application angular5 et je suis confronté au même problème. quand je passe par la documentation angulaire, ils fournissent la meilleure solution pour gérer les événements du routeur. Vérifiez la documentation suivante.
Événements de routeur dans Angular Route événements dans angular5
Mais spécifiquement pour le cas en question, nous avons besoin de NavigationEnd Event
Représente un événement déclenché lorsqu'une navigation se termine avec succès
Comment l'utiliser?
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 l'utiliser?
Dans mon cas, mon application partage un tableau de bord commun pour tous les utilisateurs tels que les utilisateurs, les administrateurs, mais j'ai besoin d'afficher et de masquer certaines options de barre de navigation 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 utilisateur connectées conformément à la réponse, j'irai pour d'autres opérations.
Les types d'œuvres suivants peuvent faire l'affaire 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 ne le souhaiterais. Le onActivate()
composant cible d'origine est appelé avant la redirection.
Il y a un @CanActivate
décorateur que vous pouvez utiliser sur le composant cible mais c'est a) non centralisé et b) ne bénéficie pas des services injectés.
Ce serait formidable si quelqu'un pouvait suggérer une meilleure façon d'autoriser centralement un itinéraire avant qu'il ne soit validé. Je suis sûr qu'il doit y avoir un meilleur moyen.
Voici mon code actuel (comment pourrais-je le changer pour écouter le changement d'itinéraire?):
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 le fais comme ça depuis RC 5
this.router.events
.map( event => event instanceof NavigationStart )
.subscribe( () => {
// TODO
} );
Modifiez simplement AppRoutingModule comme
@NgModule({
imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })],
exports: [RouterModule]
})
J'écrirais quelque chose comme ceci:
ngOnInit() {
this.routed = this.router.events.map( event => event instanceof NavigationStart )
.subscribe(() => {
} );
}
ngOnDestroy() {
this.routed.unsubscribe();
}
event._root.children[0].value._routeConfig.data
espérant qu'il puisse y avoir une meilleure façon