![](/img/trans.png)
[英]Angular - ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked
[英]Angular 4: `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked
我的子模塊中的每個EventEmiiter都會出現此錯誤,但我無法找到解決方法。
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.
這是觸發我的EventEmitter的原因:
ngOnChanges(changes: any) {
if (changes.groupingTabValid) {
if (changes.groupingTabValid.currentValue !== changes.groupingTabValid.previousValue) {
this.groupingTabValidChange.emit(this.groupingTabValid);
}
}
}
這是我的“主要”組件的HTML
<year-overview-grouping [definitionDetails]="definitionDetails"
[fixedData]="fixedData"
[showValidation]="showValidation"
[groupingTabValid]="groupingTabValid"
(groupingTabValidChange)="setValidators('groupingTab', $event)">
</year-overview-grouping>
哪個叫這個功能
public setValidators(validator: string, e: boolean) {
switch (validator) {
case "groupingTab":
this.groupingTabValid = e;
break;
case "selectionTab":
this.selectionTabValid = e;
break;
}
if (this.groupingTabValid && this.selectionTabValid) {
this.valid = true;
} else {
this.valid = false;
}
}
1)在一個簡單的解釋中,是什么導致了這個錯誤?
2)我可以采取哪些措施來解決這個問題?
遵守單向數據流規則
嘗試使用setTimeout將調用推遲一個tick
if (changes.groupingTabValid.currentValue !== changes.groupingTabValid.previousValue) {
setTimeout(() => this.groupingTabValidChange.emit(this.groupingTabValid), 0)
}
只需導入ChangeDetectionStrategy,然后將其添加到組件中
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'app-bla-bla-bla',
templateUrl: './xxxxx'
})
您可以避免使用setTimeout
並告訴Angular在初始檢查后即將發生更改。
你可以注入ChangeDetectorRef
到您的組件,並使用其markForCheck
方法。
/* ... */
constructor(private cdr: ChangeDetectorRef) {}
/* ... */
if (changes.groupingTabValid.currentValue !== changes.groupingTabValid.previousValue {
this.cdr.markForCheck();
this.groupingTabValidChange.emit(this.groupingTabValid);
}
我自己剛開始看這個異常類型,所以沒有專家,但假設它是在那里停止反饋循環。
我看不出任何明顯的原因,你想要將值發送給孩子並備份到父,但假設孩子應用了一些額外的邏輯。 對我來說,在服務而不是子組件中應用任何其他邏輯似乎更好。
我意識到plunker代碼沒有循環,但Angular機制似乎相當簡單 - 只需在循環結束時重新檢查值。 請注意,您的問題代碼中的groupingTabValid會直接反饋。
查看給定的plunker代碼,從結構上可以在父級上處理對年齡的更改。 click事件將是(click)=changeAge(age.value)
和方法(在父級上)來處理它
changeAge(inputAge) {
this.newAge = inputAge;
this.person.age = inputAge;
}
這是一個掠奪者的叉子。 改良的plunker
子組件仍然更新person.age,但不再導致錯誤,因為該值與父項上設置的值相同。
我有同樣的問題。 為了解決這個問題,我做了這個小小的黑客。
setTimeout((()=>this.valueSelect.emit(idChange)), 0);
其中“this.valueSelect.emit(idChange)”是我將發出的變化
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.