我有2个必须传递信息的子组件。
parent.component.html
<childA [loading]="loading">
<childB (loadingChanged)="loadingChangedHandler($event)"></childB>
</childA>
parent.component.ts
loading = false;
constructor(){
......
}
loadingChangedHandler(loadingChild: boolean){
this.loading = loadingChild;
}
childB.component.ts(将变量传递给父级,该值传递给子级A)
....
@Output() loadingChanged: EventEmitter<boolean> = new EventEmitter();
....
loadData() {
this.loadingChanged.emit(true);
this.service.readDate()
.subscribe((data: any) => {
........
this.loadingChanged.emit(false);
})
}
最后在childA组件中,我必须接收变量并执行操作
childA.component.ts
@Input() loading: boolean = false
constructor() {
....}
....
在子级A中,我有一个正在运行的加载微调器,但是在控制台中出现错误:
错误错误:ExpressionChangedAfterItHasBeenCheckedError:表达 检查后已更改。先前的值:'loading:false'。 当前值:“加载中:true”。
我该如何解决问题? 有关于它的文档(ngAfterViewInit),但我不明白为什么在我的情况下它不起作用。
答案 0 :(得分:0)
Angular运行更改检测,当发现传递到子组件的某些值已更改时,Angular会引发错误ExpressionChangedAfterItHasBeenCheckedError Read here in detail
要解决您的问题,可以使用 childA.component.ts
中的AfterContentChecked生命周期挂钩import { ChangeDetectorRef, AfterContentChecked} from '@angular/core';
constructor(
private cdref: ChangeDetectorRef) { }
ngAfterContentChecked() {
this.cdref.detectChanges();
}
答案 1 :(得分:0)
Imp:Angular,在开发模式下运行两次更改检测。
由于在第一个更改检测阶段中,它确定父组件的加载属性已更改,因此在下一个更改检测周期中,它观察到子组件再次更改了加载属性,因此由于加载而抛出异常在第一个周期检查完所有属性后,属性就更改了。
在生产模式下,您不会收到此错误,因为在生产模式下,更改检测仅运行一次。这就是为什么打开开发模式很重要的原因,这样我们才能提前知道这些类型的错误,这些错误会导致数据和视图之间的不一致。
在setTimeout中放置修改加载属性的代码,以确保在完成上一次更改检测后的下一个刻度中运行该代码。
尝试放置this.loadingChanged.emit(false);在setTimeout中为0。
setTimeout(() => {
this.loadingChanged.emit(false);
}, 0);