7

如果在路由期间来自组件(构造函数或 ngOnInit)的未捕获错误,则导航将不再起作用。

即使 RouterModule 有一个全局 ErrorHandler 和一个 ErrorHandler 也会发生这种情况,添加了一个 ZoneListener 以确保为好 - 请参阅 app.module.ts

这里的最小示例: https ://embed.plnkr.co/L19S3hKWyqgKUIT1EJlI/preview

确保打开控制台。单击“示例组件”后,由于 ExampleFormComponent 中的强制错误,会出现一些堆栈跟踪。之后,您将无法导航回“主页”。

如何处理意外的、未捕获的错误以确保它们不会破坏整个应用程序?

4

1 回答 1

2

我会做一些解决方法,例如:

let hasRouterError = false;
@Injectable()
export class MyErrorHandler implements ErrorHandler {
  constructor(private inj: Injector) {}

  handleError(error: any): void {
    console.log('MyErrorHandler: ' + error);

    if(hasRouterError) {
      let router = this.inj.get(Router);
      router.navigated = false;
    }

    //throw error; // it is necessarily otherwise handleError won't be executed during next error
  }
}

export function MyRouterErrorHandler(error: any) {
  console.log('RouterErrorHandler: ' + error);
  hasRouterError = true;
  throw error;
}

我们必须使用自定义RouteReuseStrategy

export class PreventErrorRouteReuseStrategy implements RouteReuseStrategy {
  shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
  store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
  shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null { return null; }
  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    if(hasRouterError) {
      hasRouterError = false;
      return false;
    }
    return future.routeConfig === curr.routeConfig;
  }
}

它与DefaultRouteReuseStrategy此代码中唯一的不同

if(hasRouterError) {
  hasRouterError = false;
  return false;
}

不要忘记将其添加到提供者数组中:

import { RouteReuseStrategy } from '@angular/router';
...
{ provide: RouteReuseStrategy, useClass: PreventErrorRouteReuseStrategy },

您可以在Modified Plunker中尝试

于 2017-05-09T17:57:11.900 回答