我创建了一个组件,表示用于修改对象详细信息的表单。该对象存在于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>
没有直接关系,因为它表示该值从false
到true
,因此似乎与表格上的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 5后才显露出来。在我的情况下,我没有使用[(ngModel)]
。我正在使用textarea仅用于显示目的(以获得材料的外观和感觉)。然而,这可能对其他人像我一样无休止地搜索有所帮助。
我发现如果你绑定到textarea的[value]
属性而不是使用插值{{}}
,那么错误就会消失。
而不是:<textarea>{{value}}</textarea>
做:<textarea [value]="value"></textarea>
您对<input>
没有任何问题,因为它是单标签元素,因此必须使用属性绑定而不是插值。 (要清楚,你只需要使用插值和value
,因为你绑定了一个只被评估过一次的属性。绑定到[value]
,这是一个属性,你不再需要{{}}
。请参阅angular docs where这个解释得很清楚。)
我怀疑通过插值,角度在第一个摘要周期将形式设置为false
,在第二个摘要时将其设置为true
,当它识别出值时。使用[value]
属性绑定,它识别第一个摘要的值。
无论如何,它都有效。
如果你使用ngModel
然后{{item.description}}
是无用的,应该足够了:
<mat-form-field class="full-width">
<textarea id=description matInput [(ngModel)]="item.description" placeholder="Description"></textarea>
</mat-form-field>
万一有人发现自己因为他们有类似的问题:
首先要检查的是确保[(ngModel)]="value"
的使用如文档中所示。如果没有,请确保您已导入FormsModule
。 Angular Material文档忽略了它,但ngModel
没有它就行不通。
我有这个错误:
ExpressionChangedAfterItHasBeenCheckedError ... Previous value: 'aria-describedby: null' Current value: 'aria-describedby: mat-error-22'
问题是我在创建表单之后和加载mat-form-field组件之前立即手动验证了我的表单。在我的情况下,我实际上没有验证我的表单,所以我删除它。