Angular 2: Retraso de detección de cambio de controlador de excepción personalizado

Estoy tratando de implementar una costumbreExceptionHandler en una aplicación Angular 2 que envía errores no detectados a una costumbreAlertsService. El objetivo es permitir que el principalApp componente para suscribirse a las alertas proporcionadas por elAlertsService para que pueda mostrar los errores en la interfaz de usuario.

El problema que veo es que los errores enviados aAlertsService por la costumbreExceptionHandler no se reflejan en la interfaz de usuario hasta que se encuentre otro error. Esto hace que la interfaz de usuario siempre esté una alerta detrás de lo que realmente proporciona elAlertsService.

Supongo que este comportamiento tiene algo que ver con la detección de cambios y el caso especial de ExceptionHandler, pero no estoy seguro de a dónde ir desde aquí. ¡Buscando ayuda de los expertos de Angular2!

Ejemplo de código a continuación, haga clic aquí: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));

Respuestas a la pregunta(1)

Su respuesta a la pregunta