2016-06-15 33 views
9

Quando un'eccezione viene catturata dal gestore di eccezioni di Angular 2, l'interfaccia utente non viene più aggiornata. Ho un esempio molto semplice qui:Angular 2 non aggiorna la vista dopo l'eccezione Viene generata

https://plnkr.co/edit/iHDYpZ3fDlO6bhOtlTbQ

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; 
 
} 
 

 
@Component({ 
 
    selector: 'my-app', 
 
    template : ` 
 
    <h3>Parent</h3> 
 
    {{aValue}} 
 
    <br/> 
 
    <br/> 
 
    <button (click)='doIt()'>do it</button> 
 
    <br/> 
 
    <br/> 
 
    <button (click)='breakIt()'>break it</button> 
 
    ` 
 
}) 
 

 
export class App implements OnInit { 
 
    private aValue: boolean = true 
 
    constructor() { } 
 
    
 
    alerts: Alert[] = []; 
 
    
 
    doIt(){ 
 
    console.log('Doing It') 
 
    this.aValue = !this.aValue 
 
    } 
 
    
 
    breakIt(){ 
 
    console.log('Breaking It') 
 
    throw new Error('some error') 
 
    } 
 
} 
 

 
bootstrap(App).catch(err => console.error(err));

Il pulsante Esegui ribalta l'booleano che si riflette nel valore interpolato nel modello. Tuttavia, una volta premuto il pulsante Interrompi (in caso di errore da generare), il valore interpolato non viene più aggiornato quando viene premuto il pulsante "Esegui". Tuttavia, la console registra ancora i messaggi "Eseguendo".

Il problema ho a che fare è Vorrei creare un gestore di eccezioni personalizzato che avvisa l'utente e, eventualmente, non certo lavoro per cancellare una forma quando qualcosa è andato storto, ma quello che sto vedendo è che se mi passi un errore su un pulsante fai clic per testarlo, tutti gli aggiornamenti dell'interfaccia utente si interrompono. Tuttavia, i pulsanti continuano a funzionare, il che significa che tutti i pulsanti che inviano richieste lo faranno se il modulo è in buono stato. L'interfaccia utente tuttavia ha smesso di aggiornare e informare l'utente di ciò che sta accadendo.

Non sono sicuro se questo è un problema con Zone o altro, ma il tentativo di un NgZone.run() non sembra risolvere il problema per me. Se si intende un errore per interrompere l'interfaccia utente di un componente, qual è l'approccio corretto al mio problema?

+0

Vedi anche http: // STA ckoverflow.com/questions/37793276/angular-2-custom-exceptionhandler-change-detection-lag/37793791#37793791 –

+0

Interessante. La differenza che sto vedendo è che l'errore è stato generato da un componente figlio e la sua vista del plunker continua ad aggiornarsi. Questo significa che ho solo bisogno di provare ... catturare il componente principale e tutti gli errori dei componenti figlio non causeranno la rottura della vista? –

+0

Non penso sia facile fare una dichiarazione generale.Questo dipende sempre da dove è stato chiamato il codice da cui viene chiamato e se questo rompe qualcosa se è stato chiamato un codice ma non è stato completato con un percorso previsto. –

risposta

1

Non fare affidamento sull'esecuzione del codice dopo un Exception non gestito. È necessario gestire l'eccezione nel punto in cui si prevede che si verifichi.

manipolazione

errore: http://www.javascriptkit.com/javatutors/trycatch.shtml

+1

Sto cercando di implementare la gestione globale delle eccezioni di Angular 2 nella speranza di non dover ricoprire tutto il mio codice con try ... catch, ma lo scenario che ho descritto mi ha fatto pensare che non potevo adottare questo approccio. Ho esaminato la domanda a cui Günter mi ha fatto riferimento, però e ora mi chiedo se posso farcela con i try-catches sui componenti principali, poiché i componenti figlio in quella domanda non interrompevano gli aggiornamenti delle viste. Non mi aspetto necessariamente che qualcosa si rompa, ma il mio vantaggio tecnico è fermamente convinto che la cattura degli errori si verifica ovunque, indipendentemente da ciò che mi aspetto. –

+0

Non è necessario avvolgere tutto in try/catch. Le eccezioni sono i tuoi amici durante lo sviluppo. Gestire le eccezioni ha senso per tutto ciò che un utente inserisce nella tua applicazione, perché sappiamo che un utente finale può fare cose pazze. Le eccezioni ti aiutano a cogliere le brutte cose che stai facendo. –

+3

Questo è quello che ho sempre fatto in passato, e sono d'accordo che le eccezioni sono i miei amici. Il problema qui è in produzione, vogliamo pubblicare errori sul server e informare l'utente che è successo qualcosa di brutto. Se Angular non aggiorna più la sua vista, non posso fare affidamento su Angular per farlo. Potrei ricorrere al puro javascript nel gestore delle eccezioni, ma stavo cercando di evitarlo. –

3

Da 4.1.1 angolare (2017-05-04) https://github.com/angular/angular/commit/07cef36

correzione (core): non si fermano rivelazione del cambiamento a causa di errori

  • impedisce l'annullamento della sottoscrizione dalla zona in caso di errore
  • impedisce l'annullamento della sottoscrizione dalla direttiva EventEmitter s su errore
  • impedisce strappatori viste in modalità dev caso di errore
  • assicura che ngOnInit viene chiamato solo 1x (anche in modalità prod)

dovrebbe funzionare senza ulteriore codice

@Component({ 
    selector: 'my-app', 
    template : ` 
    {{aValue}} 
    <button (click)='doIt()'>do it</button> 
    <button (click)='breakIt()'>break it</button> 
    ` 
}) 

export class App implements OnInit { 
    private aValue: boolean = true 

    doIt(){ 
    console.log('Doing It') 
    this.aValue = !this.aValue 
    } 

    breakIt(){ 
    console.log('Breaking It') 
    throw new Error('some error') 
    } 
} 

Plunker Example

+0

grazie mille. Cercherò di aggiornare e vedere. –