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

Joh*_*ood 7 data-binding angular

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

export class AppComponent {
  selectedItem: Item;
}
Run Code Online (Sandbox Code Playgroud)

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

<item-details [(item)]="selectedItem"></item-details>
Run Code Online (Sandbox Code Playgroud)

在组件内,各个字段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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

ExpressionChangedAfterItHasBeenCheckedError
Run Code Online (Sandbox Code Playgroud)

该错误不直接连到<textarea>,因为它说的是,从价值就falsetrue,因此似乎相关valid,在表格上财产在暗示这里.

有趣的是,我可以通过修改内容<textarea></textarea>之后的内容来避免错误:

<textarea ...>{{item.description}} </textarea>
Run Code Online (Sandbox Code Playgroud)

但这只有在item.description没有的情况下才有效null.当它null出现时我再次收到错误.

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

我已经阅读了有关'ExpressionChangedAfterItHasBeenCheckedError'错误文章的所有内容.引用文章"我不建议使用它们,而是重新设计您的应用程序".

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

and*_*rob 16

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

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

代替: <textarea>{{value}}</textarea>

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

您没有任何问题,<input>因为它是单标签元素,因此必须使用属性绑定而不是插值.(要清楚,你value只需要使用插值,因为你绑定了一个只被评估过一次的属性.绑定到[value],这是一个属性,你不再需要它{{}}.请参阅角度文档,其中解释了这一点非常清楚.)

我怀疑通过插值,angular将表单设置为false第一个摘要周期,并设置为第二个摘要,就像true它识别值一样.使用[value]属性绑定,它可以识别第一个摘要的值.

无论如何,它都有效.

  • 谢谢,这让我发疯。您的建议已解决。 (2认同)