角2路由器事件侦听器

如何监听角2路由器的状态变化?

在 Angular 1.x 中,我使用了这个事件:

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

因此,如果我在角度2中使用这个事件侦听器:

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

它不返回‘ ok’,然后从 JS 改变状态,只有这样才能运行浏览器 history. back ()函数。

使用 router.ordering ()函数作为服务:

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

我将这个服务注入到其他组件中,如本例中所示。然后我改变状态,console.info ()在服务中不工作。

我做错了什么?

119904 次浏览

新路由器

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将上升。

参见

要侦听所有状态更改,扩展默认的 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/

您可以使用 instanceof作为 @ G ünterZöchbauer的应答

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

或者您可以使用 更懒惰方法,但是请记住构造函数名可以在函数仍然工作时轻松更改!

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

角2路由器事件有不同的类别,从 router.events可观察到的传递到订阅的事件可以是 NavigationEndNavigationCancelNavigationErrorNavigationStart。实际触发路由更新的将是 NavigationEnd

我会远离使用 instanceofevent.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”-> import

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

在控制台中跟踪 true show routeEvents 控制台中的 false hide routeEvents

还可以使用 filter()过滤事件。

但是不要 只是使用 filter(e => e is NavigationEnd)

一个更好的解决方案是像下面这样在 filter()中添加一个“类型保护”:

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

它包含两件事:

  • e is NavigationEnd这是您要定义函数的断言(这是类型脚本语法,完全从已翻译的 javascript 中去掉了)
  • 这是检查类型的实际运行时代码

这样做的好处是,管道中更深处的操作符,比如下面的 map,现在知道类型是 NavigationEnd,但是如果没有类型保护,就会有类型 Event

如果您只需要检查一个事件类型,那么这是最干净的方法。这在严格模式下似乎也是必要的,以避免编译器错误。

enter image description here

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

有了 @ besPunky/angle-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

直接来自 医生

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)或者你得到在网络风暴列队错误。