Angular5 Selectbox打开一个模态 - > ExpressionChangedAfterItHasBeenCheckedError

时间:2018-05-16 07:52:20

标签: angular

Hey Stackoverflow社区,

我发现了一个奇怪的问题,发现了一个肮脏的解决方法。 这里的问题,我有一个选择框有一些选项。如果用户选择一个特定的选项,我会显示一个模态框,但这里有问题,当我打开模式时,用户点击该选项时出现错误。控制器在这里是ReactiveForms的FormControl

controle.valueChanges.subscribe(value => {
  if (value === 'SOME_EQUALS') {
    this.modalService.open<SomeModalComponent>(SomeModalComponent);
  }
});

确切错误:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ng-untouched: true'. Current value: 'ng-untouched: false'.

肮脏的解决方法是,在那个值是quals的那一刻我期望我分离ChangeDetectionRef然后打开模态,当我关闭模态我重新连接cdr ...

controle.valueChanges.subscribe(value => {
  if (value === 'SOME_EQUALS') {
    // ChangeDetectionRef
    this.cdr.detach();

    const modal = this.modalService.open<SomeModalComponent>(SomeModalComponent);
    modal.onClose().subscribe(() => this.cdr.reattach());
    modal.onDismiss().subscribe(() => this.cdr.reattach());
  }
});

你知道一种更美丽的方式吗?

3 个答案:

答案 0 :(得分:1)

我假设您使用材质库?

如果是这样,您必须绑定到复选框的更改事件:

@Output()
change: EventEmitter<MatCheckboxChange>

Event emitted when the checkbox's checked value changes.

通过这样做,这应该摆脱你的错误。

如果没有,你仍然可以尝试用超时包裹你的模态开头:

setTimeout(() => this.modalService.open<SomeModalComponent>(SomeModalComponent));

答案 1 :(得分:0)

使用detectChanges():

controle.valueChanges.subscribe(value => {
    if (value === 'SOME_EQUALS') {
        this.modalService.open < SomeModalComponent > (SomeModalComponent);
    }
}).add(() => {
    this.cd.detectChanges();
});

答案 2 :(得分:0)

我有完全相同的问题(使用 Angular 9)。在没有完全理解潜在问题的情况下,我找到了一个相对简单的解决方案: 您可以在打开模态之前手动将表单字段标记为已触摸:

controle.valueChanges.subscribe(value => {
  if (value === 'SOME_EQUALS') {
    this.controle.markAsTouched(); // to prevent ExpressionChangedAfterItHasBeenCheckedError
    this.modalService.open<SomeModalComponent>(SomeModalComponent);
  }
});