请考虑以下代码:
//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弹出一次,并且只记录一次错误。
关于如何实现这一目标的任何想法?
答案 0 :(得分:1)
在handleError()
的末尾抛出错误。
来源:https://github.com/scttcper/ngx-toastr/issues/564#issuecomment-419910273
这不是ngx-toastr的问题。
正在发生的事情是,如果出现诸如模板错误之类的错误 并且您已经“处理”了错误,更改检测将继续运行 一遍又一遍地导致无限循环。您需要在以下位置抛出错误 函数的结尾。
但是,由于未处理的HTTP错误(以及其他较小的错误 可以轻松处理),也将在最后抛出错误,并且 导致更改检测停止运行。诀窍是只扔一个 最后,当您无法处理或发生错误时 应该会导致更改检测停止运行(例如模板错误)