需要一个在路由激活时触发一个事件, 但是在网上找了很多方法, 都不太符合需求
当前在 ngOnInit 事件里的代码是这样的sidenav-menus.component.ts
ngOnInit(): void {
// ActivationEnd
this.router.events.pipe(filter((event: any) => event instanceof ActivationEnd)).subscribe(() => {
// console.log(123)
});
// ActivationStart
this.router.events.pipe(filter((event: any) => event instanceof ActivationStart)).subscribe(() => {
// console.log(123)
});
// NavigationStart
this.router.events.pipe(filter((event: any) => event instanceof NavigationStart)).subscribe(() => {
console.log(123)
});
}
我用以上其中任意一种, 在页面首次加载(刷新)的时候, 都不会触发事件
只有点击菜单进行路由切换后才输出123
我的理解是首次加载也应该是一个路由激活, 为什么不会触发 console.log(123)
呢?
是用的方法不对吗?
要实现这样的需求只能在事件外面加吗?
ngOnInit(): void {
console.log(123)
// NavigationStart
this.router.events.pipe(filter((event: any) => event instanceof NavigationStart)).subscribe(() => {
console.log(123)
});
}
花了点时间,写了个demo,可见:根组件是可以获取到全部的路由事件的,但为什么子组件获取不到,我感觉你可能需要了解下对生命周期和执行顺序的相关概念。
我举个例子:
路由 /a 对应 A组件, 路由 /a/b 对应 B 组件。
此时的顺序是,先获取到了
/a
,然后路由去查找路由表,从这时候开始一个新的路由事件就有了,而此时 A 组件并没有被实例化,也就是说向 A 组件导航的时候 A 还没有出生呢。此时,我们在
/a
的前提下,去点击/a/b
,此时A组件正在生命周期中,实例还存在(实际上不存在,也不影响订阅的代码,只是建议在组件销毁时应该取消相关订阅),所以A组件是能够获取路由变化的。而此时如果 B 组件中也有相同的订阅路由事件的代码,由于 B 组件的出生在这个路由事件之后,所以 B 组件的订阅同样也是无法订阅到相关事件的。那么当前在 A 中是没有办法获取到它出生前的事件了。如果想获取到导航到 A 的事件信息,1可以去它的父路由对应的组件中去是监听,2可以去查看 A 组件获取到路由的快照信息。
看你上面的内容,应该是在菜单组件中没有获取到,那么你需要确认的是:在你想获取的路由事件之前,菜单组件就已经实例化成功了,而菜单组件实例化晚于路由事件,那么是不行的。
如果你对这个需求有特别的感情,建议可以创建一个service,并把它注入到根组件。然后在service中订阅路由事件,同时在service中声明一个带有缓存功能的 BehaviorSubject,然后在菜单组件中去订阅这个BehaviorSubject,也是可以的。
结论: 你可以在根组件中订阅到所有的路由事件,因为根组件早于路由出生。而在其它的本身就依托于路由的组件中,无法订阅到所有的路由事件。