我创建了 test case ,以根据Routing Angular documentation和其中live demo重现我看到的问题。
现场演示稍作修改,以便请求浏览器桌面通知,并在app.component.ts
[浏览器通知代码从某处粘贴]中显示简单通知。
请注意下面的通知onclick
处理程序。它只是登录到控制台并导航到应用程序的原始路线之一。
notification.onclick = function () {
console.log('onclick');
self.router.navigate(['/heroes']);
};
要重现此问题,请确保在新窗口中打开,并允许该应用在出现提示时显示桌面通知。授予权限后,将立即显示通知。单击通知后,您将注意到路由器导航到新URL但未呈现任何内容。控制台输出显示' onclick'如预期但没有ngOnInit()
。 heroes.component.ts
也被修改为输出ngOnInit()
,如下所示,但这种情况从未发生过。如果您点击Heroes
按钮,ngOnInit()
将按预期工作。
ngOnInit() {
console.log('ngOnInit');
this.getHeroes();
}
经过一些调试后发现路由器按预期导航,heroes
组件被实例化(当构造函数被调用时),但ngOnInit()
永远不会执行。
似乎浏览器桌面通知的onclick
上下文以某种方式搞砸了Angular的内部。这是真的发生了什么?这是某种Angular bug吗?
我也尝试使用ng-push,但观察到相同的行为。
在我自己的成熟应用程序中,行为略有不同。最终会调用ngOnInit()
,但在组件构造函数执行后最多需要10秒。在等待期间,浏览器似乎闲置不使用CPU。
我很困惑。有任何想法吗?单击按钮时路由如何正常工作但是当从浏览器桌面通知的点击处理程序中使用时,它会演示这种奇怪的行为?
请注意我已经测试了最新的Chrome(67.0.3396.87),Firefox(60.0.2)和Edge(所有这些都在Windows 10上进行了最新更新)。
答案 0 :(得分:5)
我不确定原因,但该方法是在Angular Zone之外运行的。这就是网址发生变化的原因,但Angular没有检测到它,因此不会调用ngOnInit
。请注意,它会在您单击清除消息按钮时运行。您可以通过在区域中运行它来简单地修复它:
notification.onclick = () => {
this.zone.run(() => {
console.log('onclick');
this.router.navigate(['/heroes']);
});
};
constructor(private router: Router, private zone: NgZone) {
}
答案 1 :(得分:-1)
这个例子也适用于我。
首先,尝试在路由中启用哈希,以消除由配置错误的Web主机引起的路由问题。您可以在主要路径配置中执行此操作:
@NgModule({
imports: [
RouterModule.forRoot(routes, {
useHash: true
})
],
exports: [RouterModule]
})
export class AppRouting {}
如果这不能解决您的问题,您应该启用路由器跟踪,希望它可以帮助您找出问题的来源:
@NgModule({
imports: [
RouterModule.forRoot(routes, {
useHash: true,
enableTracing: true
})
],
exports: [RouterModule]
})
export class AppRouting {}
您的路线/组件是懒散地还是急切地加载?