Javascript Angular 2 路由器事件监听器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35912932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:22:39  来源:igfitidea点击:

Angular 2 router event listener

javascriptangulartypescriptangular2-routing

提问by Yegor

How to listen state change in Angular 2 router?

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

In Angular 1.x I used this event:

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

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

So, if I use this eventlistener in Angular 2:

所以,如果我在 Angular 2 中使用这个事件监听器:

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

it isn't return 'ok', then change state from JS, only then browser history.back() function run.

它不是返回“ok”,然后从 JS 更改状态,然后才运行浏览器 history.back() 函数。

Use router.subscribe() function as the service:

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

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 service in component which init in 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) {}
}

I inject this service in other components such as in this example. Then I change state, console.info() in service not working.

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

What I do wrong?

我做错了什么?

回答by Günter Z?chbauer

new router

新路由器

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

old

老的

Inject the Router and subscribe to route change events

注入路由器并订阅路由变化事件

import {Router} from 'angular2/router';

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

NOTE

笔记

For the new router, don't forget to import NavigationStartfrom routermodule

对于新的路由器,不要忘记NavigationStartrouter模块导入

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

because if you don't import it instanceofwill not work and an error NavigationStart is not definedwill rise.

因为如果你不导入它就instanceof不会工作并且错误NavigationStart is not defined会增加。

See also

也可以看看

回答by Simon_Weaver

You can also filter events with filter().

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

But don't justuse filter(e => e is NavigationEnd)

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

A much better solution is to add a 'type guard' to filter()like this:

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

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

It contains two things:

它包含两件事:

  • e is NavigationEndthis is the assertion you're defining a function for (this is typescript syntax)
  • e instanceof NavigationEndthis is the actual runtime code that checks the type
  • e is NavigationEnd这是您为其定义函数的断言(这是打字稿语法)
  • e instanceof NavigationEnd这是检查类型的实际运行时代码

The nice thing with this is that operators further down 'the pipe', like mapbelow now know the type is NavigationEnd, but without the type-guard you'd have a type Event.

这样做的好处是操作员在“管道”map下方,如下所示,现在知道类型是NavigationEnd,但是如果没有类型保护,您将拥有类型Event

If you only need to check for one event type then this is the cleanest way to do so. This also appears to be necessary in strict mode to avoid compiler errors.

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

enter image description here

在此处输入图片说明

回答by Khaled Al-Ansari

You can use instanceofas @GünterZ?chbaueranswered

您可以使用instanceof@GünterZ?chbauer回答

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

or you can use a lazierapproach, but remember constructor name can be changed easily while the function is still working!

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

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

回答by Y. Brahimi

The angular 2 router events has different classes, and what gets passed to the subscription from the router.eventsobservable can either be NavigationEnd, NavigationCancel, NavigationError, or NavigationStart. The one that will actually trigger a routing update will be NavigationEnd.

角2个路由器事件有不同的类别,什么被传递到订阅从router.events观察到的可以是NavigationEndNavigationCancelNavigationError,或NavigationStart。真正触发路由更新的将是NavigationEnd.

I would stay away from using instanceofor event.constructor.namebecause after minificationthe class names will get mangled it will not work correctly.

我会远离使用,instanceof或者event.constructor.name因为在缩小后类名会被破坏,它将无法正常工作。

You can use the router's isActivefunction instead, shown here https://angular.io/docs/ts/latest/api/router/index/Router-class.html

您可以改用路由器的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
  }
}

回答by David Alejandro Marin Alzate

in angular2, go to file "app.modules.ts"->imports

在 angular2 中,转到文件“app.modules.ts”->imports

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

in enableTracing true show routeEvents in console in enableTracing false hide routeEvents in console

在 enableTracing true 在控制台中显示 routeEvents 在 enableTracing false 在控制台中隐藏 routeEvents

回答by San Jaisy

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

回答by Marcel van der Drift

To listen to all state changes, extend the default RouterOutlet and add your own logic in 'activate' and 'deactivate' handlers.

要侦听所有状态更改,请扩展默认 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!');
  }
}

Copied from 'Custom Router Outlet' example here: https://auth0.com/blog/2016/01/25/angular-2-series-part-4-component-router-in-depth/

从此处的“自定义路由器插座”示例复制:https: //auth0.com/blog/2016/01/25/angular-2-series-part-4-component-router-in-depth/