Comment écouter le changement d'état dans le routeur angulaire 2?
Dans Angular 1.x, j'ai utilisé cet événement:
$rootScope.$on('$stateChangeStart',
function(event,toState,toParams,fromState,fromParams, options){ ... })
Donc, si j'utilise cet eventlistener dans Angular 2:
window.addEventListener("hashchange", () => {return console.log('ok')}, false);
il n'est pas renvoyé 'ok', puis changez d'état à partir de JS, puis exécutez la fonction history.back () du navigateur.
Utilisez la fonction router.subscribe () en tant que service:
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');
})
}
}
Injecter le service dans le composant qui init in dans le routage:
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) {}
}
J'injecte ce service dans d'autres composants, comme dans cet exemple. Ensuite, je change d'état, console.info () dans le service ne fonctionne pas.
Ce que je fais mal?
nouveau routeur
constructor(router:Router) {
router.events.subscribe(event:Event => {
if(event instanceof NavigationStart) {
}
// NavigationEnd
// NavigationCancel
// NavigationError
// RoutesRecognized
});
}
vieux
Injecter le routeur et s'abonner aux événements de changement d'itinéraire
import {Router} from 'angular2/router';
class MyComponent {
constructor(router:Router) {
router.subscribe(...)
}
}
REMARQUE
Pour le nouveau routeur, n'oubliez pas d'importer le module NavigationStart
à partir du module router
import { Router, NavigationStart } from '@angular/router';
parce que si vous ne l'importez pas, instanceof
ne fonctionnera pas et une erreur NavigationStart is not defined
augmentera.
Voir également
Vous pouvez utiliser instanceof
comme @ GünterZöchbauer répondu
this.router.events.subscribe(event => {
if(event instanceof NavigationStart) {
// do something...
}
}
ou vous pouvez utiliser une approchelazier, mais rappelez-vous que le nom du constructeur peut être changé facilement tant que la fonction est encore active!
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
Vous pouvez également filtrer les événements avec filter()
.
Mais n'utilisez pas seulementfilter(e => e is NavigationEnd)
Une solution bien meilleure consiste à ajouter un "garde de type" à filter()
comme ceci:
filter((e): e is NavigationEnd => e instanceof NavigationEnd),
Il contient deux choses:
e is NavigationEnd
c'est l'assertion pour laquelle vous définissez une fonction (c'est la syntaxe TypeScript)e instanceof NavigationEnd
c'est le code d'exécution réel qui vérifie le typeLa bonne chose à cela est que les opérateurs plus bas dans le tuyau, comme map
ci-dessous savent maintenant que le type est NavigationEnd
, mais sans le type-guard vous auriez un type Event
.
Si vous ne devez rechercher qu'un seul type d'événement, c'est la manière la plus propre de le faire. Cela semble également être nécessaire en mode strict pour éviter les erreurs de compilation.
dans angular2, allez dans le fichier "app.modules.ts" -> importations
RouterModule.forRoot(
appRoutes,
{
enableTracing: true
}
)
dans enableTracing true Voir routeEvents dans consolein enableTracing false masquer RouteEvents dans console
Les événements de routeur angulaires 2 ont différentes classes et ce qui est transmis à l'abonnement depuis l'observable router.events
peut être NavigationEnd
, NavigationCancel
, NavigationError
ou NavigationStart
. Celui qui déclenchera réellement une mise à jour de routage sera NavigationEnd
.
Je voudrais éviter d'utiliser instanceof
ou event.constructor.name
car après minification, les noms de classe seront mutilés, cela ne fonctionnera pas correctement.
Vous pouvez utiliser la fonction isActive
du routeur à la place, comme indiqué ici 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
}
}