我有一个父组件,它显示验证错误列表并呈现子组件列表ngFor
.每个子组件在执行期间执行其验证,ngOnInit
并将结果输出到父组件.父组件侦听此输出并更新验证错误列表,其结果将引发错误:
Expression has changed after it was checked
现在,我理解为什么抛出这个错误 - 在更改检测周期的开始,验证错误处于一个状态,最后它处于另一个状态,这是不允许的.
我不明白的是如何解决这个问题.父组件必须在页面顶部显示错误列表,每个子组件都会将其验证结果添加到此列表中.如果这是对单向数据流的破坏,那么请告诉我如何以干净的方式解决这个问题(即,不将验证包装在一个中setTimeout
,而不是从不可变列表更改为可变列表,而不是显式调用验证后再次更换检测器).
Plunker再现问题:https://plnkr.co/edit/q52A1DraNOnxZa0qGFDo?p = preview
编辑
我通过构造EventEmitter
带有isAsync
标志来"解决"了这个问题:
new EventEmitter(true)
这意味着将以异步方式发出值,因此将在下一个更改检测周期中拾取发出的值.我想结果与包装逻辑相同,setTimeout
但这样至少我们不必将代码包装在超出我们可能发出值的任何地方.
Angular 不喜欢变更检测本身引起变更并由ngOnInit
变更检测调用。
在 devMode 中,更改检测会在每次常规更改检测运行后执行一次额外的更改检测,以检查模型是否稳定。如果模型在更改检测期间发生更改,则会引发此错误。
您可以将更改延迟到使用以下命令完成更改检测之后
ngOnInit() {
setTimeout(() => {
this.output.emit({value: true});
}
}
Run Code Online (Sandbox Code Playgroud)
更新(请参阅下面 Ghetolay 的评论)
ngOnInit
不会由更改检测调用,您可以在其中进行绑定更改。您不能做的是从子级更改父级,ngOnInit
因为这会破坏单向数据流。
另请参阅https://github.com/angular/angular/issues/10131#issuecomment-233369491
归档时间: |
|
查看次数: |
1639 次 |
最近记录: |