解釋 Angular 錯誤:'Expression Changed After It Has Been Checked'


我的一位同事在開發 Angular 前端應用程序時遇到了一個錯誤訊息,錯誤訊息為:

ExpressionChangedAfterItHasBeenCheckedError:Expression在檢查之後已更改。先前的值:'null',當前的值:'true'。

這個錯誤發生在他開發一個從第二頁導航回第一頁的後退按鈕功能時。第一頁已經渲染過一次,並需要以不同的初始值重新渲染。

這個錯誤的根本原因在於Angular的變更檢測機制。每次操作後,Angular都會將用於該操作的值存儲在組件視圖的 oldValues 屬性中。一旦所有組件都已經檢查過,Angular就會啟動下一個摘要週期。但是,它不進行操作,而是將當前值與上一個週期存儲的值進行比較。

值得注意的是,這種額外的檢查只在開發模式中發生。Angular從組件樹的頂部到底部強制執行單向數據流。一旦父組件的變更已經被處理,就不允許任何子組件更新父組件的屬性。

要解決上述問題,可能的解決方案包括使用異步更新,如 setTimeout,或者在 ngAfterViewInit() 的生命週期鉤子中手動觸發變更檢測,利用 _changeDetectorRef.detectChanges()ChangeDetectorRef 類提供以下五種方法:

抽象類 ChangeDetectorRef {
 抽象 markForCheck(): void;
 抽象 detach(): void;
 抽象 detectChanges(): void;
 抽象 checkNoChanges(): void;
 抽象 reattach(): void;
}

通過利用這些方法,您可以手動運行變更檢測並更新子視圖。我的同事很高興發現錯誤在這種解釋之後得到了解決。