[英]Angular 2 router event listener
Angular 2路由器中如何監聽state變化?
在 Angular 1.x 中我使用了這個事件:
$rootScope.$on('$stateChangeStart',
function(event,toState,toParams,fromState,fromParams, options){ ... })
所以,如果我在 Angular 2 中使用這個事件監聽器:
window.addEventListener("hashchange", () => {return console.log('ok')}, false);
它不返回“確定”,然后從 JS 更改 state,然后瀏覽器 history.back() function 運行。
使用 router.subscribe() function 作為服務:
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');
})
}
}
在路由中初始化的組件中注入服務:
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) {}
}
我將此服務注入到其他組件中,例如本例中的組件。 然后我更改 state,console.info() in service not working。
我做錯了什么?
新路由器
constructor(router:Router) {
router.events.subscribe(event:Event => {
if(event instanceof NavigationStart) {
}
// NavigationEnd
// NavigationCancel
// NavigationError
// RoutesRecognized
});
}
老的
注入路由器並訂閱路由變化事件
import {Router} from 'angular2/router';
class MyComponent {
constructor(router:Router) {
router.subscribe(...)
}
}
筆記
對於新的路由器,不要忘記從router
模塊中導入NavigationStart
import { Router, NavigationStart } from '@angular/router';
因為如果你不導入它, instanceof
將不起作用,並且NavigationStart is not defined
會出現錯誤。
也可以看看
您還可以使用filter()
過濾事件。
但不要只使用filter(e => e is NavigationEnd)
更好的解決方案是向filter()
添加一個“類型保護”,如下所示:
filter((e): e is NavigationEnd => e instanceof NavigationEnd),
它包含兩件事:
e is NavigationEnd
這是您為其定義函數的斷言(這是打字稿語法,完全從轉譯的 javascript 中剝離出來)e instanceof NavigationEnd
這是檢查類型的實際運行時代碼這樣做的好處是操作員在“管道”下方,例如下面的map
,現在知道類型是NavigationEnd
,但是如果沒有類型保護,您將擁有類型Event
。
如果您只需要檢查一種事件類型,那么這是最簡潔的方法。 這在嚴格模式下似乎也是必要的,以避免編譯器錯誤。
您可以使用@GünterZöchbauer回答的instanceof
this.router.events.subscribe(event => {
if(event instanceof NavigationStart) {
// do something...
}
}
或者您可以使用更懶惰的方法,但請記住,在函數仍在工作時可以輕松更改構造函數名稱!
this.router.events.subscribe(event => {
if(event.constructor.name === "NavigationStart") {
// do something...
}
});
直接來自文檔
import {Event, RouterEvent, Router, NavigationEnd} from '@angular/router';
this.router.events.pipe(
filter((e: any): e is RouterEvent => e instanceof RouterEvent)
).subscribe((evt: RouterEvent) => {
if (evt instanceof NavigationEnd) {
console.log(evt.url)
}
})
盡管文檔提供了代碼filter((e: Event)
但我將其更改為filter((e: any)
否則您會在 WebStorm 中遇到 linting 錯誤。
import { Router,NavigationEnd } from '@angular/router';
constructor(private route:Router){
this.routeEvent(this.route);
}
routeEvent(router: Router){
router.events.subscribe(e => {
if(e instanceof NavigationEnd){
console.log(e)
}
});
}
angular 2 路由器事件有不同的類,從router.events
observable 傳遞給訂閱的router.events
可以是NavigationEnd
、 NavigationCancel
、 NavigationError
或NavigationStart
。 真正觸發路由更新的是NavigationEnd
。
我將遠離使用instanceof
或event.constructor.name
因為在縮小后類名將被破壞,它將無法正常工作。
您可以改用路由器的isActive
函數,如下所示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
}
}
在 angular2 中,轉到文件“app.modules.ts”->imports
RouterModule.forRoot(
appRoutes,
{
enableTracing: true
}
)
在 enableTracing true 在控制台中顯示 routeEvents 在 enableTracing false 在控制台中隱藏 routeEvents
有了@bespunky/angular-zen,這變得簡單多了……
基本上,擴展RouteAware
類並創建一個on<EventType>()
方法:
import { Component } from '@angular/core';
import { NavigationStart, NavigationEnd, RoutesRecognized } from '@angular/router';
import { RouteAware } from '@bespunky/angular-zen/router-x';
@Component({
selector : 'app-demo',
templateUrl: './demo.component.html',
styleUrls : ['./demo.component.css']
})
export class DemoComponent extends RouteAware
{
// ✨ Any router event can have a handler method.
// See https://angular.io/guide/router#router-events for a complete list of angular's router events.
// ✨ Use `this.router` to access the router
// ✨ Use `this.route` to access the activated route
// ✨ Use `this.componentBus` to access the RouterOutletComponentBus service
protected onNavigationStart(event: NavigationStart): void
{
console.log(`Navigation started for: ${event.url}`);
}
protected onRoutesRecognized(event: RoutesRecognized): void
{
console.log('Recognized routes.');
}
protected onNavigationEnd(event: NavigationEnd): void
{
console.log(`Navigation ended for: ${event.url}`);
}
}
看看這個答案: https : //stackoverflow.com/a/64864103/4371525
閱讀有關Angular路由事件的博客,您將獲得有關路由事件和調試的詳細信息。
要偵聽所有狀態更改,請擴展默認 RouterOutlet 並在“激活”和“停用”處理程序中添加您自己的邏輯。
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!');
}
}
從此處復制的“自定義路由器插座”示例: https : //auth0.com/blog/2016/01/25/angular-2-series-part-4-component-router-in-depth/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.