在textarea上使用[(ngModel)]绑定时如何避免ExpressionChangedAfterItHasBeenCheckedError

问题描述 投票:4回答:4

我创建了一个组件,表示用于修改对象详细信息的表单。该对象存在于app.component.ts中:

export class AppComponent {
  selectedItem: Item;
}

它通过双向绑定传递到app.component.html的组件中,如下所示:

<item-details [(item)]="selectedItem"></item-details>

在组件内,Item的各个字段绑定到输入控件,以允许用户更新数据,例如:

<mat-form-field class=name>
  <input matInput [(ngModel)]="item.name" value="{{item.name}}" required placeholder="Name">
  <mat-error>Item name can not be left blank</mat-error>
</mat-form-field>

一切都很好,直到我到达textarea:

<mat-form-field class="full-width">
  <textarea id=description matInput [(ngModel)]="item.description" placeholder="Description">{{item.description}}</textarea>
</mat-form-field>        

它工作,但它抛出一个例外:

ExpressionChangedAfterItHasBeenCheckedError

该错误与<textarea>没有直接关系,因为它表示该值从falsetrue,因此似乎与表格上的valid属性有关,如暗示here

有趣的是,我可以通过修改<textarea></textarea>的内容来避免错误,例如在内容后面加一个空格:

<textarea ...>{{item.description}} </textarea>

但这只有在item.description不是null时才有效。当它是null然后我再次得到错误。

我正在触发selectedItem从另一个子组件的更改,该组件也对selectedItem具有双向绑定。当用户选择一个项目时,新的Item会向上流向应用程序,然后返回到详细信息组件。

我读过Everything you need to know about the 'ExpressionChangedAfterItHasBeenCheckedError' error文章。引用文章“我不建议使用它们,而是重新设计您的应用程序”。

大!怎么样?如何构造事物以便控件A用于选择Item,而控件B用于编辑它?控件A和B在没有触发此错误的情况下相互通信的正确方法是什么?

angular data-binding
4个回答
10
投票

这个错误让我非常疯狂,它只在升级到Angular 5后才显露出来。在我的情况下,我没有使用[(ngModel)]。我正在使用textarea仅用于显示目的(以获得材料的外观和感觉)。然而,这可能对其他人像我一样无休止地搜索有所帮助。

我发现如果你绑定到textarea的[value]属性而不是使用插值{{}},那么错误就会消失。

而不是:<textarea>{{value}}</textarea>

做:<textarea [value]="value"></textarea>

您对<input>没有任何问题,因为它是单标签元素,因此必须使用属性绑定而不是插值。 (要清楚,你只需要使用插值和value,因为你绑定了一个只被评估过一次的属性。绑定到[value],这是一个属性,你不再需要{{}}。请参阅angular docs where这个解释得很清楚。)

我怀疑通过插值,角度在第一个摘要周期将形式设置为false,在第二个摘要时将其设置为true,当它识别出值时。使用[value]属性绑定,它识别第一个摘要的值。

无论如何,它都有效。


0
投票

如果你使用ngModel然后{{item.description}}是无用的,应该足够了:

<mat-form-field class="full-width">
   <textarea id=description matInput [(ngModel)]="item.description" placeholder="Description"></textarea>
</mat-form-field>

0
投票

万一有人发现自己因为他们有类似的问题:

首先要检查的是确保[(ngModel)]="value"的使用如文档中所示。如果没有,请确保您已导入FormsModule。 Angular Material文档忽略了它,但ngModel没有它就行不通。

另见Why (ngModel) is not working?


0
投票

我有这个错误:

ExpressionChangedAfterItHasBeenCheckedError ... Previous value: 'aria-describedby: null' Current value: 'aria-describedby: mat-error-22'

问题是我在创建表单之后和加载mat-form-field组件之前立即手动验证了我的表单。在我的情况下,我实际上没有验证我的表单,所以我删除它。

© www.soinside.com 2019 - 2024. All rights reserved.