在抛出异常后,角2不会更新视图

时间:2022-05-18 00:07:39

When an exception is caught by Angular 2's exception handler, the UI no longer 'updates'. I have a very simple example here:

当一个异常被角2的异常处理程序捕获时,UI将不再“更新”。我有一个非常简单的例子:

https://plnkr.co/edit/iHDYpZ3fDlO6bhOtlTbQ

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

The Do It button flips the boolean which is reflected in the interpolated value in the template. However, once the Break It button is pressed (which cases an error to be thrown), the interpolated value no longer updates when the 'Do it' button is hit. However, the console still logs the messages 'Doing it'.

Do It按钮翻转了反映在模板内插值中的布尔值。但是,一旦按下了Break It按钮(如果要抛出一个错误),当“Do It”按钮被击中时,插入值不再更新。然而,控制台仍然记录消息“执行它”。

The problem I'm dealing with is I would like to create a custom exception handler that warns the user and possibly does some work to clear a form when something has gone wrong, but what I'm seeing is if I throw an error on a button click to test it, all UI updates stop. However, buttons continue to function, meaning any buttons that post requests will do so if the form is in a good state. The UI however has ceased to update and inform the user what is happening.

我处理的问题是我想创建一个自定义异常处理程序,警告用户,可能做一些清理工作表单的时候已经错了,但是我看到的是如果我抛出一个错误按钮上点击测试它,停止所有UI更新。但是,按钮继续发挥作用,这意味着,如果表单处于良好状态,任何发布请求的按钮都将这样做。然而,UI已经停止更新并通知用户正在发生的事情。

I'm not sure if this is a problem with Zones or something else, but attempting an NgZone.run() didn't seem to solve the problem for me. If an error is meant to break a component's UI, what's the correct approach to my problem?

我不确定这是否是zone或其他问题,但是尝试使用NgZone.run()似乎并不能解决这个问题。如果一个错误是要破坏一个组件的UI,那么我的问题的正确方法是什么?

2 个解决方案

#1


3  

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

自角4.1.1(2017-05-04)起,https://github.com/angular/angular/commit/07cef36

fix(core): don’t stop change detection because of errors

修正(核心):不要因为错误而停止变更检测

  • prevents unsubscribing from the zone on error
  • 防止在错误时从区域取消订阅
  • prevents unsubscribing from directive EventEmitters on error
  • 防止对错误的指示事件发射器取消订阅。
  • prevents detaching views in dev mode if there on error
  • 如果出现错误,防止在开发模式下分离视图
  • ensures that ngOnInit is only called 1x (also in prod mode)
  • 确保ngOnInit只被调用1x(也在prod模式下)

it should work without additional code

它应该在没有附加代码的情况下工作

@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

砰砰作响的例子

#2


1  

Don't rely on code execution after an unhandled Exception happened. You have to handle the exception in the place where you expect it to happen.

在未处理的异常发生后,不要依赖代码执行。您必须在期望发生异常的地方处理异常。

Error handling: http://www.javascriptkit.com/javatutors/trycatch.shtml

错误处理:http://www.javascriptkit.com/javatutors/trycatch.shtml

#1


3  

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

自角4.1.1(2017-05-04)起,https://github.com/angular/angular/commit/07cef36

fix(core): don’t stop change detection because of errors

修正(核心):不要因为错误而停止变更检测

  • prevents unsubscribing from the zone on error
  • 防止在错误时从区域取消订阅
  • prevents unsubscribing from directive EventEmitters on error
  • 防止对错误的指示事件发射器取消订阅。
  • prevents detaching views in dev mode if there on error
  • 如果出现错误,防止在开发模式下分离视图
  • ensures that ngOnInit is only called 1x (also in prod mode)
  • 确保ngOnInit只被调用1x(也在prod模式下)

it should work without additional code

它应该在没有附加代码的情况下工作

@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

砰砰作响的例子

#2


1  

Don't rely on code execution after an unhandled Exception happened. You have to handle the exception in the place where you expect it to happen.

在未处理的异常发生后,不要依赖代码执行。您必须在期望发生异常的地方处理异常。

Error handling: http://www.javascriptkit.com/javatutors/trycatch.shtml

错误处理:http://www.javascriptkit.com/javatutors/trycatch.shtml