其他参考:Angular踩坑-ExpressionChangedAfterItHasBeenCheckedError异常 - 天天看点

原因

Angular 的变更检测机制(Change Detection) 一般只在开发模式下出现,在生产环境下是不会抛出的,不过最好解决一下,这个机制本质上是为了避免数据不同步。

在开发模式下,Angular 会进行两次变更检测:

  1. 第一次:正常运行变更检测。
  2. 第二次:检查是否有模型数据在第一次变更检测后又被修改。

如果 Angular 发现某个绑定表达式(例如模板中的 {{ property }}[property])在第一次变更检测之后被修改了,就会抛出这个错误。

解决方法

可以考虑使用  ChangeDetectorRef  手动触发一次完整变更检测:

export class TestComponent {
    constructor(private cdr: ChangeDetectorRef) { }

    refresh(){
        ...更新内容...
        this.cdr.detectChanges(); //手动触发一次变更检测
    }
}

原理

当你调用:this.cd.detectChanges();,相当于手动触发一次变更检测,让 Angular 提前完成一次完整的变更检测周期,之后执行的两轮Angular 变更检查就不会出现值不同的情况。

具体流程:

  1. 用户对数据进行更新操作
  2. 数据更新操作(假设在refresh()执行)
  3. 数据更新完成,手动调用了 this.cdr.detectChanges()
    • Angular 会立即执行一次变更检测(完整的一轮)
    • 更新视图,绑定值被更新
  4. Angular 继续执行它自己的第一轮变更检测(Check 1)
  5. Angular 执行第二轮变更检测(Check 2)

类比说明

你可以把 Angular 的自动变更检测想象成:

每天两次的保安巡逻(上午一次,下午一次),检查是否有异常。

detectChanges() 就像是:

你主动通知保安:“现在就去检查一遍。”

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐