Angular触发NG0100表达式检测后变更错误,访问ViewChild属性时出现
错误原因
这个NG0100: ExpressionChangedAfterItHasBeenCheckedError是Angular开发模式下的变更检测校验提示,触发原因是同一轮变更检测周期内,模板绑定的表达式值发生了改变。
你当前场景的具体逻辑是:
@ViewChild查询的子组件实例会在变更检测执行过程中完成赋值,子组件app-deal-idle-disposition初始化后才会给自身metricsData赋值。父组件模板直接绑定了dispositionDetails?.metricsData,Angular第一轮检测时这个值还是null,子组件初始化完成后值更新为目标对象,变更检测后置校验就会抛出该错误。
解决方案
方案1:父组件本地变量存储子组件属性(成本最低)
父组件新增本地变量存储需要用到的子组件属性,在AfterViewInit生命周期中完成赋值,同时手动触发变更检测消除冲突:
import { Component, OnInit, AfterViewInit, ViewChild, ChangeDetectorRef } from '@angular/core'; export class DealDetailsComponent implements OnInit, AfterViewInit { @ViewChild('pmrDetails') pmrDetails: any; @ViewChild('dispositionDetails') dispositionDetails: any; // 新增本地变量存储指标数据 pmrMetrics: any; dispositionMetrics: any; constructor(private cdr: ChangeDetectorRef) {} ngAfterViewInit() { if (this.pmrDetails) { this.pmrMetrics = this.pmrDetails.metricsData; } if (this.dispositionDetails) { this.dispositionMetrics = this.dispositionDetails.metricsData; } // 手动触发一轮变更检测同步值 this.cdr.detectChanges(); } }
模板部分替换原有绑定即可:
<!-- 原有取值替换为本地变量 --> {{dispositionMetrics | json}} <!-- 编辑态指标组件的editData也替换 --> [editData]="pmrMetrics || dispositionMetrics"
方案2:子组件通过@Output抛出数据(符合数据流规范)
避免父组件直接读取子组件内部属性,子组件把metricsData通过事件抛给父组件,父组件接收后存储到本地变量再绑定,耦合度更低,从根源避免该类问题:
子组件新增Output事件:
// app-deal-idle-disposition.component.ts 以及 app-deal-pmr.component.ts 中新增 import { Output, EventEmitter } from '@angular/core'; @Output() metricsDataChange = new EventEmitter<any>(); // 自身metricsData赋值完成后抛出事件 ngOnInit() { // 原有逻辑处理完metricsData后 this.metricsDataChange.emit(this.metricsData); }
父组件模板监听事件:
<app-deal-pmr #pmrDetails *ngIf="urlData.dealType === 'Portfolio Management Restructure'" (metricsDataChange)="pmrMetrics = $event" <!-- 其余原有属性保持不变 --> > </app-deal-pmr> <app-deal-idle-disposition #dispositionDetails *ngIf="urlData.dealType === 'Idle Disposition'" (metricsDataChange)="dispositionMetrics = $event" <!-- 其余原有属性保持不变 --> > </app-deal-idle-disposition>
内容的提问来源于stack exchange,提问作者Ananya Amar
相关产品推荐
相关产品推荐

