简体   繁体   English

使用 ReactiveForms 和 NgbModal 时的 ExpressionChangedAfterItHasBeenCheckedError

[英]ExpressionChangedAfterItHasBeenCheckedError when using ReactiveForms and NgbModal

I have a reactive form and when the user presses the ESC key in an input i would like to show an "are you sure" modal before the form gets hidden.我有一个反应式表单,当用户在输入中按下 ESC 键时,我想在表单隐藏之前显示一个“你确定”模式。
As soon as the modal is shown i get the following exception in the console:一旦显示模态,我就会在控制台中收到以下异常:

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

Here is a stackblitz that shows the issue (focus input and press ESC) 这是一个显示问题的 stackblitz (焦点输入并按 ESC)

Note: When you focus the input, blur and focus again the issue wont appear as ng-untouched wont change again.注意:当您聚焦输入,模糊并再次聚焦时,问题不会显示为ng-untouched不会再次改变。

Is there any workaround?有什么解决方法吗? Whats the recommended way to implement such a functionality?实现此类功能的推荐方法是什么?

Thanks in advance!提前致谢!

Try this:尝试这个:

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

I finally found a way to overcome the issue but still having the dirty flag maintained.我终于找到了解决这个问题的方法,但仍然保留了脏标志。

ng-untouched is maintained onBlur when FormControl is set to {updateOn:'change'} (the default).当 FormControl 设置为{updateOn:'change'} (默认值)时,ng-untouched 保持在 onBlur 上。 What you have to do is simply blur the input manually before opening the modal.您要做的只是在打开模态之前手动模糊输入。 When the modal is shown it will blur anyway.当显示模态时,它无论如何都会模糊。

Here is a stackblitz 这是一个堆栈闪电战

Another trick is to blur the activeElement before opening the dialog.另一个技巧是在打开对话框之前blur activeElement。 Here is an example that displays a modal dialog when new is selected.这是一个在选择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);
        }
      });
    }
  }
}

Try to wrap the onESC block of code inside setTimeout, which will trigger Angular Change detection using zone.js.尝试将 onESC 代码块包装在 setTimeout 中,这将使用 zone.js 触发 Angular Change 检测。

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

It's not the issue of keyup event rather it's an issue of custom modal which you are using.这不是 keyup 事件的问题,而是您正在使用的自定义模式的问题。 Try to remove the modal and it will work or you need to initialize it first.尝试删除模态,它会起作用,或者您需要先对其进行初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM