2016-03-10 13 views
41

Jak odczytywać zmianę stanu w routerze Angular 2?Słyszalny odbiornik zdarzeń routera 2

kątowej 1.x Kiedyś to wydarzenie:

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

Więc, jeśli mogę użyć tego EventListener kątowej 2:

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

to nie jest powrót 'OK', a następnie zmienić stan z JS, tylko wtedy działa funkcja przeglądarki history.back(). Funkcja

Zastosowanie router.subscribe() jako usługa: obsługa

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

inject składnika, który inicjujący ułożenia:

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

wstrzyknięcie tej usługi w innych składników, takich jak w tym przykładzie . Wtedy zmieniam stan, console.info() w serwisie nie działa.

Co robię źle?

+0

Możliwy duplikat [Jak wykryć zmianę trasy w An gular 2?] (https://stackoverflow.com/questions/33520043/how-to-detect-a-route-change-in-angular-2) –

Odpowiedz

96

nowy router

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

stary

wstrzyknąć routera i zapisać się do wydarzeń Zmień trasę

import {Router} from 'angular2/router'; 

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

UWAGA

Dla nowego routera, nie zapomnij, aby importować NavigationStart z router modułu

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

bo jeśli go nie importować instanceof nie zadziała i błąd wzrośnie.

Zobacz także

+0

Czy muszę uruchomić 'router.subscribe (...)' w każdej klasie czy mogę je prowadzić jednorazowo? W dokumentach nie rozumiem, jakie parametry muszę wprowadzić w funkcji subskrypcji? Czy możesz napisać pełny przykład? –

+0

Możesz zrobić to raz w usłudze globalnej, a następnie wprowadzić usługę tam, gdzie chcesz uzyskać dostęp. –

+0

Jeśli wstrzyknę to jako usługę w innych składnikach, to nie zwróci żadnych danych. –

-1

Aby wysłuchać wszystkich zmian stanu, rozszerzenie domyślnego RouterOutlet i dodać własną logikę w 'Activate' i 'wyłączyć' ładowarki.

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

Skopiowane z przykładu 'Niestandardowe Ruter wylot' tu: https://auth0.com/blog/2016/01/25/angular-2-series-part-4-component-router-in-depth/

5

Można użyć instanceof jak @ GünterZöchbauer odpowiedział

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

lub można użyć Lazier podejście , ale pamiętaj, że nazwa konstruktora może być łatwo zmieniona, dopóki funkcja nadal działa!

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

Jakie są wasze rozważania, aby nie używać 'instanceof'? –

+2

To podejście jest również kruche do zminimalizowania, ponieważ nazwa konstruktora może zostać zmieniona, np. 'Event.constructor.name' może być' 'A'' –

0

kątowe 2 zdarzenia router różnych klas, a co zostanie przekazane do subskrypcji z router.events obserwowalnym może być albo NavigationEnd, NavigationCancel, NavigationError lub NavigationStart. Ten, który faktycznie uruchomi aktualizację routingu, będzie NavigationEnd.

chciałbym zatrzymać się z dala od używania instanceof lub event.constructor.name bo po minifikacji nazwy klasy dostanie zniekształcone nie będzie działać prawidłowo.

można korzystać z funkcji routera isActive zamiast pokazanego tutaj 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

w angular2, przejdź do pliku "app.modules.ts" -> import

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

w enableTracing prawdziwy pokaz routeEvents in console w enableTracing false hide routeEvents in console

Powiązane problemy