在关闭 Angular material 对话框之前检查用户对 Reactive 表单的更改

Check for user changes of a Reactive form inside an Angular material dialog before closing it

我在 Angular Material 对话框中有一个 ReactiveForm,它接收一些数据来编辑它,我想阻止用户在他输入内容并试图退出对话框时关闭它。

如果它没有被修改然后关闭它而不询问任何东西但是如果它是,我想显示一个对话框说它被修改了,你确定要关闭它吗?

我尝试使用 valueChanges,但它显示确认对话框的次数与字母更改的次数一样多。

这是我现在拥有的:

ngOnInit() {
  this.preventCloseModal();
  this.source = this.commonFunctions.getSourceFromUrl(this.router.url);
  this.getRequest(this.data);
  this.getNinjas();
  this.getStatus();
}

preventCloseModal() {
  this.addForm.valueChanges.pipe(
    debounceTime(2000),
    distinctUntilChanged()
  ).subscribe(
    (data) => {
      if (this.addForm.dirty) {
        this.dialogRef.disableClose = true;
        this.dialogRef.backdropClick().subscribe(_ => {
          let cn = confirm('Estas seguro que deseas cerrar ? Perderas todos los progresos no guardados.')
          if (cn) {
            this.dialogRef.close();
          }
        })
      }
    });
}

编辑 1:

我还尝试了以下方法:

async ngOnInit() {
  this.addForm.valueChanges.subscribe((res) => {
    this.isValueChanged = true;
  });
  this.source = this.commonFunctions.getSourceFromUrl(this.router.url);
  this.getRequest(this.data);
  this.getNinjas();
  this.getStatus();
}

@HostListener('window:keyup.esc') onKeyUp() {
  if (this.isValueChanged) {
    // console.log('show alert');
    this.dialogRef.disableClose = true;
    this.dialogRef.backdropClick().subscribe(_ => {
      let cn = confirm('Estas seguro que deseas cerrar ? Perderas todos los progresos no guardados.')
      if (cn) {
        this.dialogRef.close();
      } else {
        return false;
      }
    })
    //return false;
  }
  this.dialogRef.close();
}

我被屏蔽了,有谁知道怎么办吗?我试过 ngDoCheck 但我创建了一个无限循环。

谢谢!

我想你的问题很简单,但执行起来似乎很难。让我为你清除它。

打开对话框时确保dialogConfig.disableClose = true;只有在触发关闭时才能关闭。按照代码。

const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.data = item;
dialogConfig.width = '76%';
dialogConfig.height = '63%';
dialogConfig.panelClass = 'custome_css_class';
const dialogRef = this.dialog.open(FormBuilderComponent, dialogConfig);

在 FormBuilderComponent 中初始化一个名为 isValueChanged 的​​变量,如下所示。

isValueChanged = false;

现在 ngOnInit() 订阅值更改。如果值更改,则像这样使 isValueChanged 为真。

async ngOnInit() {
  this.templateForm.valueChanges.subscribe(() => {
      this.isValueChanged = true;
   });
}

当您单击按钮关闭模态检查 isValueChanged 时否。如果是这样,则显示您的警报。如果为假,则关闭模态。

clocseModal() {
   if(this.isValueChanged) {
      // console.log('show alert');
       return false;
   }
 this.dialogRef.close();
}

好的,所以我找到了适合我的方法。

我做的第一件事是:
当用后端数据填充表单时,我将其设置为原始且未修改。

this.addForm.markAsUntouched;
this.addForm.markAsPristine;

之后,我检查用户是否按下了 Esc 键,或者他是否按下了模态框外。

对于 Esc 键,我这样做了:

@HostListener('window:keyup.esc') onKeyUp() {
    if (this.addForm.dirty) {
        this.dialogRef.disableClose = true;
        let cn = confirm('Estas seguro que deseas cerrar ? Perderas todos los progresos no guardados.')
        if (cn) {
            this.dialogRef.close();
        } else {
            return false;
        }
    }
    this.dialogRef.close();
}

对于背景点击我做了这个:

constructor(
        ...
) {
        dialogRef.disableClose = true;
        dialogRef.backdropClick().subscribe(() => {
            if (this.addForm.dirty) {
                this.dialogRef.disableClose = true;
                let cn = confirm('Estas seguro que deseas cerrar ? Perderas todos los progresos no guardados.')
                if (cn) {
                    this.dialogRef.close();
                } else {
                    return false;
                }
            }

            this.dialogRef.close();
        })
    }

如您所见,它是相同的代码,但具有一些不同的逻辑,目前,它有效,我想与像我一样被困住的人分享我的答案。现在它只需要一个我会做的重构,这样我就不会重复代码而且它看起来更干净了。

非常感谢@sibabrat swain 的回答!