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()
问题就消失了
- 我们想出了两个解决方案
- 前
patchValue()
运行一个this._changeDetectionRef.detectChanges();
。并将 ngIf
更改为 [hidden]
,以便完全构建表单和 DOM。不利的一面是时间和内存成本,因为完整的表格和相关的 DOM 被创建(这在许多应用程序中可能不是问题,但它对我们来说是因为我们有一个巨大的表格)。
- 更好的解决方案是在组件中应用
patchValue()
(或 setValue()
,如果数据和字段是 1:1),因此只有在 ngOnInit()
.
我还没有提交这些更改 (22/3/17)。
这是我之前 post 关于 Angular2(带有 TS 的 beta 3)中嵌套表单的一种延续 (
您可以在 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()
中跨多个组件嵌套和构建的模型反应形式。其中一些表单在模板 中折叠为 - 数据也在
ngOnInit()
中读入,并且正在使用theModelForm.patchValue(data)
应用
- 展开其中一个折叠的表单时出现此错误。这与 DOM 未构建的事实有关,因为表单是在
ngOnInit()
中创建的,直到展开后才触发。取出patchValue()
问题就消失了 - 我们想出了两个解决方案
- 前
patchValue()
运行一个this._changeDetectionRef.detectChanges();
。并将ngIf
更改为[hidden]
,以便完全构建表单和 DOM。不利的一面是时间和内存成本,因为完整的表格和相关的 DOM 被创建(这在许多应用程序中可能不是问题,但它对我们来说是因为我们有一个巨大的表格)。 - 更好的解决方案是在组件中应用
patchValue()
(或setValue()
,如果数据和字段是 1:1),因此只有在ngOnInit()
.
- 前
ngIf
我还没有提交这些更改 (22/3/17)。