使用 ReactiveForms 和 NgbModal 时出现 ExpressionChangedAfterItHasBeenCheckedError

ExpressionChangedAfterItHasBeenCheckedError when using ReactiveForms and NgbModal

我有一个反应式表单,当用户在输入中按下 ESC 键时,我想在表单隐藏之前显示一个 "are you sure" 模式。
一旦显示模式,我就会在控制台中收到以下异常:

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

Here is a stackblitz 显示问题(焦点输入并按 ESC)

注意: 当您聚焦输入、模糊并再次聚焦时,问题不会出现,因为 ng-untouched 不会再次改变。

有什么解决办法吗?实现此类功能的推荐方法是什么?

提前致谢!

尝试将 onESC 代码块包装在 setTimeout 中,这将触发 Angular 使用 zone.js 进行更改检测。

onEsc() {
  setTimeout(()=>{
    const modalRef = this.modalService.open(NgbdModalContent);
    modalRef.componentInstance.name = 'World';
  }, 0);
}

试试这个:

this.form = new FormGroup({
  test: new FormControl('',{updateOn:'submit'})
})

这不是 keyup 事件的问题,而是您正在使用的自定义模式的问题。尝试删除模态框,它会起作用,否则您需要先对其进行初始化。

我终于找到了解决问题的方法,但仍然保留了脏标志。

当 FormControl 设置为 {updateOn:'change'}(默认值)时,

ng-untouched 在 Blur 上保持不变。您所要做的只是在打开模式之前手动模糊输入。当显示模态时,它无论如何都会模糊。

Here is a stackblitz

另一个技巧是在打开对话框之前 blur activeElement。这是一个在选择 new 时显示模式对话框的示例。

{
  type: 'select',
  key: 'destination',
  templateOptions: {
    label: 'To Account',
    options: [...accounts],
    required: true,
    disabled: false,
  },
  hooks: {
    onInit: (field) => {
      field.form.get('destination').valueChanges.subscribe((value) => {
        if( value == 'new' ){
            (document.activeElement as any).blur();
            this.modal.open(AddAccountDialogComponent);
        }
      });
    }
  }
}