javascript evenements Écouteur d'événement de routeur angulaire 2




evenement onkeyup javascript (5)

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 routing:

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?


Answer #1

Les événements de routeur 2 angulaires 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 la minification, les noms de classe seront mutilés, ils ne fonctionneront pas correctement.

Vous pouvez utiliser la fonction isActive du routeur à la place (voir 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
  }
}

Answer #2

dans angular2, allez dans le fichier "app.modules.ts" -> imports

RouterModule.forRoot(
      appRoutes,
      { 
         enableTracing: true
      }
)

dans enableTracing true show routeEvents dans la console dans enableTracing false masquer routeEvents dans la console


Answer #3

Vous pouvez également filtrer les événements avec filter() .

Mais n'utilisez pas simplement le filter(e => e is NavigationEnd)

Une solution bien meilleure consiste à ajouter un 'type guard' à 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 dactylographiée)
  • e instanceof NavigationEnd il s’agit du code d’exécution réel qui vérifie le type

La bonne chose à cela est que les opérateurs plus bas dans le tuyau, comme la map ci map dessous savent maintenant que le type est NavigationEnd , mais sans la protection de type, vous auriez un type Event .

Si vous n'avez besoin de 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.


Answer #4

Vous pouvez utiliser instanceof comme réponse à @ GünterZöchbauer

this.router.events.subscribe(event => {
  if(event instanceof NavigationStart) {
    // do something...
  }
}

ou vous pouvez utiliser une approche plus paresseuse , mais souvenez-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...
  }
});

Answer #5

Pour écouter tous les changements d'état, étendez le RouterOutlet par défaut et ajoutez votre propre logique dans les gestionnaires "activer" et "désactiver".

import {Directive} from 'angular2/core';
import {Router, RouterOutlet, ComponentInstruction} from 'angular2/router';

@Directive({
  selector: 'router-outlet'
})

export class MyOwnRouterOutlet extends RouterOutlet {
  ...

  activate() {
    console.log('Hello from the new router outlet!');
  }
}

Copié à partir de l'exemple "Custom Router Outlet": https://auth0.com/blog/2016/01/25/angular-2-series-part-4-component-router-in-depth/





angular2-routing