我正試圖在Angular 2應用程序中實現自定義ExceptionHandler
,該應用程序向未定義的AlertsService
提交未被捕獲的錯誤。目標是允許主要App
組件訂閱AlertsService
提供的警報,以便它可以在UI中顯示錯誤。Angular 2:自定義ExceptionHandler更改檢測延遲
我看到的問題是,直到遇到其他錯誤時,自定義ExceptionHandler
提交給AlertsService
的錯誤纔會反映在UI中。這會導致UI永遠只是AlertsService
實際提供的內容之一。
我的猜測是,這種行爲與變化檢測和ExceptionHandler的特殊情況有關,但我不確定從哪裏去。期待Angular2專家的幫助!下面
示例代碼,普拉克在這裏:https://plnkr.co/edit/xPoWCELA9IHqeLBS4wXs?p=preview
import { Component, ExceptionHandler, Injectable, OnInit, provide } from '@angular/core';
import { bootstrap } from '@angular/platform-browser-dynamic';
import { Subject } from 'rxjs/Subject'
export interface Alert {
message: string;
}
@Injectable()
export class AlertsService {
private alertTriggeredSubject = new Subject<Alert>();
alertTriggered = this.alertTriggeredSubject.asObservable();
triggerAlert(message: string) {
this.alertTriggeredSubject.next(<Alert>{ message: message });
}
}
@Injectable()
export class CustomExceptionHander {
constructor(private alertsService: AlertsService) { }
call(exception, stackTrace = null, reason = null) {
this.alertsService.triggerAlert(exception.originalException);
console.error('EXCEPTION:', exception);
}
}
@Component({
selector: 'child-component',
template : `
<h3>Child</h3>
<div id="child">
<button (click)="breakMe()">Break Me!</button>
<div>Alerts Sent:</div>
<ul><li *ngFor="let error of errors">{{error}}</li></ul>
</div>`
})
export class ChildComponent {
errors: string[] = [];
numErrors = 0
breakMe() {
this.numErrors++;
let error = `I broke it (${this.numErrors})`;
// The error added to the array below is never reflected in the
// "Alerts Sent:" <ul>...not sure why
this.errors.push(error);
console.info('ChildComponent.errors', this.errors);
// Simulate unhandled exception
throw new Error(error);
}
}
@Component({
selector: 'my-app',
template : `
<h3>Parent</h3>
<div id="parent">
<div>Alerts Received:</div>
<ul><li *ngFor="let alert of alerts">{{alert.message}}</li></ul>
<child-component></child-component>
</div>`
directives: [ChildComponent]
})
export class App implements OnInit {
constructor(private alertsService: AlertsService) { }
alerts: Alert[] = [];
ngOnInit() {
this.alertsService.alertTriggered.subscribe(alert => {
this.alerts.push(alert);
// Alert gets received, but is not reflected in the UI
// until the next alert is received, even thought the
// alerts[] is up-to-date.
console.info('App alert received:', alert);
console.info('App.alerts:', this.alerts);
});
}
}
bootstrap(App, [
AlertsService,
provide(ExceptionHandler, { useClass: CustomExceptionHander })
]).catch(err => console.error(err));
感謝您的快速響應。因此,如果我正確理解這一點,則更新異常處理程序以手動觸發更改檢測以處理因異常而未觸發更改檢測的情況?不完全直觀,但它的作品。 – WayneC
我想在異常之後做一個額外的更改檢測週期是安全的。它不應該太頻繁;-)可能有更好的方法。我不是自定義異常處理程序實現方面的專家。 –
在我接受此標記之前,請遵循一個問題。另外,在按鈕點擊處理程序中,錯誤被推送到ChildComponent的錯誤[]。即使我們現在在ExceptionHandler中手動運行更改檢測,該值也不會在UI中更新。任何想法爲什麼? – WayneC