雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

Angular UT报错Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError

2024-06-17 83

有一个Angular的Component的单元测试代码,执行后fixture.detectChanges();

就会报错Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value for 'showLoading': 'true'. Current value: 'false'. Find more at https://angular.io/errors/NG0100

代码是这样的,只是在ngAfterViewInit方法里修改了showLoading的值。

export class StartComponent implements AfterViewInit {
    showLoading = true;
    ngAfterViewInit(): void {
        this.showLoading = false;
    }
}

UT的代码是这样的:

describe('StartComponent', () => {
  let component: StartComponent;
  let fixture: ComponentFixture<StartComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [StartComponent]
    })
      .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(StartComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

ExpressionChangedAfterItHasBeenCheckedError 错误通常发生在 Angular 的变更检测周期中,它表明在变更检测期间,某些表达式的值已经被修改,这与预期不符合。

在的情况下,fixture.detectChanges() 触发了变更检测,但在变更检测期间,某些属性(如 showLoading)的值发生了变化。由于 Angular 在变更检测期间检测到了这个不一致,因此抛出了 ExpressionChangedAfterItHasBeenCheckedError 错误。

解决这个问题的方法之一是使用 Angular 的生命周期钩子来进行处理。可以使用 ngAfterViewInit() 或 ngAfterContentInit() 钩子来在组件视图初始化完成后再执行的变更操作。这样可以确保在 Angular 完成视图的初始化之后再进行变更操作,避免了在变更检测周期内引起的不一致性。

另外,还可以使用 setTimeout() 来将变更操作推迟到下一个 JavaScript 事件循环中。这样可以使变更操作在 Angular 的变更检测周期之外进行,从而避免了错误的发生。

总之,避免在变更检测周期内修改属性值是解决这个错误的关键。使用 Angular 的生命周期钩子或将变更操作推迟到下一个 JavaScript 事件循环中是解决这个问题的两种常见方法。

更新于:5个月前
赞一波!

文章评论

评论问答