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
Angular 2 router event listener
提问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 NavigationStart
from router
module
对于新的路由器,不要忘记NavigationStart
从router
模块导入
import { Router, NavigationStart } from '@angular/router';
because if you don't import it instanceof
will not work and an error NavigationStart is not defined
will 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 NavigationEnd
this is the assertion you're defining a function for (this is typescript syntax)e instanceof NavigationEnd
this 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 map
below 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.
如果您只需要检查一种事件类型,那么这是最干净的方法。这在严格模式下似乎也是必要的,以避免编译器错误。
回答by Khaled Al-Ansari
You can use instanceof
as @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.events
observable can either be NavigationEnd
, NavigationCancel
, NavigationError
, or NavigationStart
. The one that will actually trigger a routing update will be NavigationEnd
.
角2个路由器事件有不同的类别,什么被传递到订阅从router.events
观察到的可以是NavigationEnd
,NavigationCancel
,NavigationError
,或NavigationStart
。真正触发路由更新的将是NavigationEnd
.
I would stay away from using instanceof
or event.constructor.name
because after minificationthe class names will get mangled it will not work correctly.
我会远离使用,instanceof
或者event.constructor.name
因为在缩小后类名会被破坏,它将无法正常工作。
You can use the router's isActive
function 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/