首页 > 解决方案 > 来自浏览器桌面通知单击事件的 Angular 6 路由会产生意外行为

问题描述

我创建了一个测试用例来重现我看到的基于Routing Angular 文档和其中找到的现场演示的问题。

现场演示稍作修改,以便请求浏览器桌面通知,并在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 的内部结构。这真的会发生吗?这是某种角度错误吗?

我也尝试过使用ng-push但观察到相同的行为。

在我自己的成熟应用程序中,行为略有不同。最终ngOnInit()会被调用,但在组件的构造函数执行后最多需要 10 秒。在等待期间,浏览器似乎处于空闲状态,不消耗 CPU。

我很困惑。有任何想法吗?单击按钮时路由如何正常工作,但在浏览器桌面通知的单击处理程序中使用时却表现出这种奇怪的行为?

请注意,我已在最新的 Chrome (67.0.3396.87)、Firefox (60.0.2) 和 Edge(均在 Windows 10 上进行了最新更新)进行了测试。

标签: angularangular-routing

解决方案


我不知道为什么,但该方法是在 Angular Zone 之外运行的。这就是为什么 url 正在改变但 Angular 没有检测到它所以ngOnInit没有被调用。请注意,例如,当您单击清除消息按钮时它会运行。您可以通过在区域中运行它来简单地修复它:

notification.onclick = () => {
    this.zone.run(() => {
        console.log('onclick');
        this.router.navigate(['/heroes']);
    });
};

constructor(private router: Router, private zone: NgZone) {

}

推荐阅读