角度 - 模板中的错误导致无限循环

时间:2018-02-08 20:26:14

标签: angular

请考虑以下代码:

//our root app component
import {ChangeDetectionStrategy, Component, ErrorHandler, Injector, NgModule, ViewContainerRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {ToastModule, ToastsManager} from "ng2-toastr/ng2-toastr";

@Component({
  selector: 'my-app',
  template: `
    <div>
      name={{(test$|async).name}}
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class App {
  test$: Observable<{name:string}> = null;

  constructor(toastr: ToastsManager, viewContainerRef: ViewContainerRef) {
    toastr.setRootViewContainerRef(viewContainerRef);
  }
}

export class CustomErrorHandler extends ErrorHandler {
  constructor(private injector: Injector) { super(); }
  handleError(err: any): void {
    super.handleError(err);
    this.injector.get(ToastsManager).error(err.message);
  }
}

@NgModule({
  imports: [ BrowserModule, BrowserAnimationsModule, ToastModule.forRoot() ],
  declarations: [ App ],
  bootstrap: [ App ],
  providers: [
    { provide: ErrorHandler, useClass: CustomErrorHandler, deps: [Injector] }
  ]
})
export class AppModule {}

也可作为Plunker here使用。

在组件模板中故意触发错误(test未定义)。自定义错误处理程序启动,记录错误并尝试弹出错误吐司。不仅不会出现吐司,而且应用程序会不断记录原始错误。挖掘一点似乎表明这是由于烤箱的setTimeout函数被重复调用引起的。我尝试用不同的烤箱库做类似的事情,但结果相同。

预期的行为是toast弹出一次,并且只记录一次错误。

关于如何实现这一目标的任何想法?

1 个答案:

答案 0 :(得分:1)

handleError()的末尾抛出错误。

来源:https://github.com/scttcper/ngx-toastr/issues/564#issuecomment-419910273

这不是ngx-toastr的问题。

正在发生的事情是,如果出现诸如模板错误之类的错误 并且您已经“处理”了错误,更改检测将继续运行 一遍又一遍地导致无限循环。您需要在以下位置抛出错误 函数的结尾。

但是,由于未处理的HTTP错误(以及其他较小的错误 可以轻松处理),也将在最后抛出错误,并且 导致更改检测停止运行。诀窍是只扔一个 最后,当您无法处理或发生错误时 应该会导致更改检测停止运行(例如模板错误)