当变更检测完成后又更改了表达式值时,Angular 就会抛出 ExpressionChangedAfterItHasBeenCheckedError
错误。Angular 只会在开发模式下抛出此错误。
在开发模式下,Angular 在每次变更检测运行后都会执行一次附加检查,以确保绑定没有更改。这会在视图处于不一致状态时捕获错误。比如,如果某个方法或 getter 每次被调用时都会返回一个不同的值,或者某个子组件更改了其父组件上的值,就可能会发生这种情况。如果发生这两种情况,则表明变更检测是不稳定的。Angular 会抛出错误以确保数据始终正确地反映在视图中,从而防止 UI 行为不稳定或可能的无限循环。
当你添加了模板表达式或开始实现生命周期钩子(比如 ngAfterViewInit
或 ngOnChanges
)时,容易发生此错误。在处理加载状态和异步操作,或者子组件更改其父组件中的绑定时,这也很常见。
如何排除本错误
CLI 生成的源码映射在调试时非常有用。请向上浏览调用栈,直到找到错误中所显示的、值已更改的模板表达式。
运行变更检测后,请确保模板中的绑定没有更改。这通常意味着需要针对你的用例进行重构以使用正确的组件生命周期钩子。如果此问题存在于 ngAfterViewInit
中,建议的解决方案是使用构造函数或 ngOnInit
来设置初始值,或者使用 ngAfterContentInit
做其他值的绑定。
如果要绑定到视图中的方法,请确保调用不会更新模板中的任何其他绑定。
在“你需要了解的关于 “ExpressionChangedAfterItHasBeenCheckedError” 错误的一切”中学习为什么该解决方案更合适,以及在 “Angular 调试:检查后表达式已更改”的简单说明(和修复)中了解为什么这样做会有用。