[英]Check for user changes of a Reactive form inside an Angular material dialog before closing it
I have a ReactiveForm in a Angular Material Dialog that receives some data to edit it, i want to prevent the user to close if it he has typed something and tried to get out of the dialog.我在 Angular 材质对话框中有一个 ReactiveForm,它接收一些数据来编辑它,我想防止用户在他输入了一些东西并试图退出对话框时关闭它。
If its not modified then close it without asking anything but if it is, i want to show a dialog that says, its modified, are you sure you want to close it?如果它没有被修改,那么在不询问任何内容的情况下关闭它,但如果是,我想显示一个对话框,上面写着,它已修改,你确定要关闭它吗?
I tried to use valueChanges but it shows the confirm dialog as many times as letters have changed.我尝试使用 valueChanges 但它显示确认对话框的次数与字母更改的次数一样多。
This is what i have right now:这就是我现在所拥有的:
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();
}
})
}
});
}
Also i tried the following:我也尝试了以下方法:
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();
}
I'm blocked, does anyone know how to do it?我被卡住了,有人知道怎么办吗? I tried ngDoCheck but i creates an infinite loop.
我尝试了 ngDoCheck 但我创建了一个无限循环。
Thank you!谢谢!
Okay so i found the way that works for me.好的,所以我找到了适合我的方式。
The first thing i did was:我做的第一件事是:
When the form is populated with back-end data, i set it to pristine and untouched.当表单填充有后端数据时,我将其设置为原始且未触及。
this.addForm.markAsUntouched;
this.addForm.markAsPristine;
After that, i check if the user has pressed Esc key or if he has pressed outside the modal.之后,我检查用户是否按下了 Esc 键,或者他是否按下了模态框外。
For the Esc key i did this:对于 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();
}
For the backdrop click i did this one:对于背景点击我做了这个:
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();
})
}
As you can see, it's the same code but with some different logic, for now, it works, i wanted to share my answer for anyone who is stucked like me.正如您所看到的,它是相同的代码,但具有一些不同的逻辑,现在,它可以工作,我想与像我一样被困住的任何人分享我的答案。 Now it just needs a refactor that i will do so i don't repeat code and it looks cleaner.
现在它只需要一个我会做的重构,这样我就不会重复代码并且它看起来更干净。
Thank you very much for your answers @sibabrat swain !非常感谢您的回答@sibabrat swain!
I guess your issues are pretty simple but the execution seems to difficult.我想你的问题很简单,但执行起来似乎很困难。 Let me clear it for you.
让我为你清除它。
While you open the dialogue box make sure dialogConfig.disableClose = true;
打开对话框时确保
dialogConfig.disableClose = true;
so that it can only be closed if you trigger to close.这样只有在触发关闭时才能将其关闭。 Follow the code.
按照代码。
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);
Inside the FormBuilderComponent initialise a variable called as isValueChanged like this.在 FormBuilderComponent 内部初始化一个名为 isValueChanged 的变量,如下所示。
isValueChanged = false;
Now inside the ngOnInit()
subscribe the value changes.现在在
ngOnInit()
中订阅值的变化。 If the value changed make isValueChanged true like this.如果值更改了,则像这样使 isValueChanged 为 true。
async ngOnInit() {
this.templateForm.valueChanges.subscribe(() => {
this.isValueChanged = true;
});
}
No while you click on the button to close the modal check isValueChanged.不,当您单击按钮关闭模式检查 isValueChanged 时。 If that is true then show your alert.
如果这是真的,那么请显示您的警报。 And if false then close the modal.
如果为假,则关闭模式。
clocseModal() {
if(this.isValueChanged) {
// console.log('show alert');
return false;
}
this.dialogRef.close();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.