wake-up-neo.net

Angular 2 Router Event Listener

Wie kann ich die Statusänderung im Angular 2-Router überwachen?

In Angular 1.x habe ich dieses Ereignis verwendet:

$rootScope.$on('$stateChangeStart',
    function(event,toState,toParams,fromState,fromParams, options){ ... })

Wenn ich diesen Eventlistener in Angular 2 verwende:

window.addEventListener("hashchange", () => {return console.log('ok')}, false);

es wird nicht 'ok' zurückgegeben, dann wird der Status von JS geändert, nur die Browser-History.back () - Funktion wird ausgeführt.

Verwenden Sie die Funktion router.subscribe () als Dienst:

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');
        })
    }
}

Injizieren Sie den Dienst in der Komponente, die init beim Routing verwendet:

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) {}
}

Ich füge diesen Dienst in anderen Komponenten ein, wie in diesem Beispiel. Dann ändere ich den Status, console.info () im Dienst funktioniert nicht.

Was ich falsch mache?

53
Egor Medvedev

neuer Router

constructor(router:Router) {
  router.events.subscribe(event:Event => {
    if(event instanceof NavigationStart) {
    }
    // NavigationEnd
    // NavigationCancel
    // NavigationError
    // RoutesRecognized
  });
}

alt

Injizieren Sie den Router und abonnieren Sie Routineänderungsereignisse

import {Router} from 'angular2/router';

class MyComponent {
  constructor(router:Router) {
    router.subscribe(...)
  }
}

HINWEIS

Vergessen Sie beim neuen Router nicht, NavigationStart aus dem Modul router zu importieren

import { Router, NavigationStart } from '@angular/router';

wenn Sie es nicht importieren, funktioniert instanceof nicht und der Fehler NavigationStart is not defined steigt.

Siehe auch 

119

Sie können instanceof als @ GünterZöchbauer answer verwenden

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

oder Sie können einenlazier- Ansatz verwenden, aber denken Sie daran, dass der Name des Konstruktors leicht geändert werden kann, während die Funktion noch arbeitet!

this.router.events.subscribe(event => {
  if(event.constructor.name === "NavigationStart") {
    // do something...
  }
});
4

Sie können Ereignisse auch mit filter() filtern. 

Aber nicht nur benutze filter(e => e is NavigationEnd)

Eine viel bessere Lösung ist, einen Funktionswächter wie folgt zu filter() hinzuzufügen:

 filter((e): e is NavigationEnd => e instanceof NavigationEnd), 

Es enthält zwei Dinge:

  • e is NavigationEnd Dies ist die Assertion, für die Sie eine Funktion definieren (dies ist die TypeScript-Syntax).
  • e instanceof NavigationEnd Dies ist der eigentliche Laufzeitcode, der den Typ überprüft

Das Schöne daran ist, dass Operatoren weiter unten in der Pipe, wie map unten, wissen, dass der Typ NavigationEnd ist, aber ohne den Typenschutz hätten Sie einen Typ Event.

Wenn Sie nur nach einem Ereignistyp suchen müssen, ist dies der sauberste Weg, dies zu tun. Dies scheint auch im strikten Modus notwendig zu sein, um Compilerfehler zu vermeiden.

 enter image description here

2
Simon_Weaver

gehen Sie in angle2 zur Datei "app.modules.ts" -> importe

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

in enableTracing true zeigen Sie routeEvents in der Konsole an in enableTracing false hide routeEvents in der Konsole

Die Router-Ereignisse in "Winkel 2" haben verschiedene Klassen. Was vom Abonnement router.events an das Abonnement übergeben wird, kann entweder NavigationEnd, NavigationCancel, NavigationError oder NavigationStart sein. Diejenige, die tatsächlich ein Routing-Update auslöst, ist NavigationEnd.

Ich würde instanceof oder event.constructor.name nicht verwenden, da die Klassennamen nach minification nicht mehr korrekt funktionieren.

Sie können stattdessen die isActive-Funktion des Routers verwenden, die hier angezeigt wird 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
  }
}
0
Y. Brahimi