Angular2 (beta3) "expression has changed after it was checked" 更新表单值

Angular2 (beta3) "expression has changed after it was checked" in updating form values

这是我之前 post 关于 Angular2(带有 TS 的 beta 3)中嵌套表单的一种延续 (),但我正在 post 编写一个新的问题,因为它指的是不同类型的问题。

您可以在 http://plnkr.co/edit/iCmmy9at2wF5qY0P6VmV 找到此处描述的问题的 repro。简而言之,在这个假想的场景中,我有一个组件代表虚构词典中的单个单词,另一个子组件用于代表该单词的每个含义;因此,父组件与其子组件之间存在一对多关系。两者都有一个基于表单的模板,使用表单生成器构建。子模板位于 NgFor 内,我在其中绑定来自父 (=word) 模型的每个含义。这样,每个词义的所有属性都会自动绑定到词的模型。

其中一些属性附加了多个验证器(自定义或标准)。我的问题是,当我以编程方式从父组件设置单词模型时(这也意味着设置表单控件的值),这似乎在验证过程中触发了一些竞争条件,这引发了几个 [=26= 类型的异常]EXCEPTION: 表达式 '!definitionCtl.valid' 在检查后发生了变化。先前值:'true'。当前值:'false',阻止进一步的代码执行。

AFAIK,似乎与此问题相关的唯一信息在这里:

然而,这些讨论似乎并没有解决我的问题,除非(如果我理解得很好)我选择手动管理我的所有绑定,我想避免这种情况,就像在真实情况下一样-world 应用程序会有很多。有人能帮忙吗?

您可以尝试禁用 Angular2 开发模式:

import {bootstrap} from 'angular2/platform/browser';
import {App} from './app';
import {enableProdMode} from 'angular2/core';

enableProdMode();

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

查看 Günter 的回答了解更多详情:

我遇到了这个问题。在 https://github.com/angular/angular/issues/6005 中对此有很多讨论。我们有不同的情况和解决方案(我刚刚在那个页面上列出了它)。

  • 我们的 Angular 应用程序 - https://github.com/GeoscienceAustralia/GNSS-Site-Manager,具有在 ngOnInit() 中跨多个组件嵌套和构建的模型反应形式。其中一些表单在模板
  • 中折叠为 ngIf
  • 数据也在 ngOnInit() 中读入,并且正在使用 theModelForm.patchValue(data)
  • 应用
  • 展开其中一个折叠的表单时出现此错误。这与 DOM 未构建的事实有关,因为表单是在 ngOnInit() 中创建的,直到展开后才触发。取出 patchValue() 问题就消失了
  • 我们想出了两个解决方案
    1. patchValue()运行一个this._changeDetectionRef.detectChanges();。并将 ngIf 更改为 [hidden],以便完全构建表单和 DOM。不利的一面是时间和内存成本,因为完整的表格和相关的 DOM 被创建(这在许多应用程序中可能不是问题,但它对我们来说是因为我们有一个巨大的表格)。
    2. 更好的解决方案是在组件中应用 patchValue()(或 setValue(),如果数据和字段是 1:1),因此只有在 ngOnInit().

我还没有提交这些更改 (22/3/17)。