在自定义错误处理程序中使用router.navigate时出错

Ped*_*rez 4 angular2-routing angular

您好,我在Angular的自定义异常处理程序中添加了路由导航,但是我遇到的问题是,当在Angular组件的onInit上触发错误时,它会进入错误循环:

错误:无法激活已经激活的插座

这是我的组件的代码:

    import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

@Injectable()
export class ErrorService implements ErrorHandler  {

  constructor(
    private injector: Injector
  ) { }

  get router(): Router {
    return this.injector.get(Router);
  };


  handleError(error: any): void {
    console.error(error);
    this.router.navigate(['error', { error: error }], { skipLocationChange: true});
  }

}
Run Code Online (Sandbox Code Playgroud)

这些是我的路线:

export const routes: Routes = [
  { path: '', redirectTo: 'browser', pathMatch: 'full' },
  { path: 'browser', loadChildren: './modules/browserui#BrowserUiModule' },
  { path: 'error', component: ErrorComponent, data: { title: 'Generic error' } },
  { path: '**', component: ErrorComponent, data: { title: '404 not found' } }
];
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?谢谢!

ghi*_*ing 6

@jonas和其他人,我实际上在全局错误处理程序中找到了一种更好的方法。setTimeout在我的情况下,我们甚至不需要那还不够,因为它是部分路由的(它正在路由,但是上一页的一部分仍保留在屏幕上,有点奇怪)。

无论如何,我在Angular仓库中找到了一个GitHub帖子,上面说使用zone。因此,在我的情况下,我想捕获401并重定向到登录页面,并且代码是如此简单:

handleError(error: any) {
   console.error(error);
   if (error.status === 401) {
     zone.run(() => router.navigate(['/login']));
   }
}
Run Code Online (Sandbox Code Playgroud)

现在,它可以按预期工作,没有任何副作用。


jon*_*nas 2

我终于让这个工作了。我的解决方案是将导航调用封装在 setTimeout() 函数中,因此我为您提供的解决方案如下所示:

handleError(error: any): void {
    console.error(error);
    setTimeout(() => this.router.navigate(['error', { error: error }], { skipLocationChange: true}));
  }
Run Code Online (Sandbox Code Playgroud)
  • 角度:4.4.4
  • Angular-cli:1.4.6
  • 打字稿:2.5.3