我的angular6项目中出现此控制台错误:错误:ExpressionChangedAfterItHasBeenCheckedError:检查表达式后,表达式已更改。先前的值:“ flag:”。当前值:“标志:空”。
这是ts组件子代中的代码
@Input() flag: any;
这是html组件子元素中的代码
<div *ngIf="flag !== 'ABBONAMENTO_MDA'">
<div class="form-group col-lg-3 col-md-3">
// something else
</div>
</div>
<div *ngIf="flag === 'ABBONAMENTO_MDA'">
<div class="form-group col-lg-3 col-md-3">
// something else
</div>
这是组件父亲中的代码
<app-repertorio
[flag]="eventoSelezionato" // here i intercept the state of flagMda
</app-repertorio>
答案 0 :(得分:0)
使用一些初始值初始化flag变量应该可以解决此问题。并且这还允许您的组件具有一个初始状态,以回退到万一通过输入eventoSelezionato
未定义标志值的情况。
@Input() flag: string = 'INITIAL_VALUE';
答案 1 :(得分:0)
只需使用钩子AfterViewChecked和Angle的ChangeDetectorRef服务即可。 变更检测器将帮助收集要检查变更的所有视图。
constructor(private cdRef: ChangeDetectorRef) {}
ngAfterViewChecked() {
this.cdRef.detectChanges();
}
答案 2 :(得分:0)
假设您有一个父组件A和一个子组件B。A组件具有名称和文本属性。在其模板中,它使用引用名称属性的表达式:
template: '<span>{{name}}</span>'
它的模板中还包含B组件,并通过输入属性绑定将text属性传递给此组件:
@Component({
selector: 'a-comp',
template: `
<span>{{name}}</span>
<b-comp [text]="text"></b-comp>
`
})
export class AComponent {
name = 'I am A component';
text = 'A message for the child component`;
...
}
因此,这是Angular运行更改检测时发生的情况。首先检查A组件。列表中的第一个操作是更新绑定,因此它将子组件的文本表达式评估为A消息,并将其向下传递给B组件,并将此值存储在视图中:
view.oldValues[0] = 'A message for the child component';
然后调用列表中提到的生命周期挂钩。
现在,它执行第三次操作,并将表达式{{name}}评估为文本“我是A组件”。它将使用此值更新DOM并将评估值放入oldValues:
view.oldValues [1] ='我是一个组件'; 然后,Angular执行下一个操作,并对子B组件运行相同的检查。检查B组件后,当前摘要循环完成。
如果Angular在开发模式下运行,那么它将运行第二个摘要,执行上面列出的验证操作。现在想象一下,在Angular将子组件的值A消息传递给B组件并将其存储后,属性文本已在A组件上更新为更新后的文本。因此,它现在运行验证摘要,第一个操作是检查属性文本是否未更改:
AComponentView.instance.text === view.oldValues [0]; //错误 '子组件的消息'==='更新后的文本'; //错误 然而它确实存在,因此Angular抛出错误ExpressionChangedAfterItHaHasBeenCheckedError。
第三个操作也是如此。如果name属性在DOM中呈现并存储后已更新,我们将得到相同的错误:
AComponentView.instance.name === view.oldValues [1]; //错误 '我是一个组件'==='更新名称'; //错误
因此可以通过以下方法强制进行更改检测来解决错误:
ngAfterViewInit() {
this.cd.detectChanges();
}