Feature Request
It should be possible to cancel the close event.
It is not possible to cancel the close event.
Use-case: Dialog with Form Model which will be sent to the server. So for example, the result of the this server call is an error, which should be displayed inside the dialog and prevent it from closing. Right now, this is only possible if I put the logic (store or service calls) inside the dialog component. This isn鈥檛 following the dumb and smart components pattern, where the logic should be put inside the container component.
Angular 7, Angular Material 7
馃憤 Also if you have a form inside a dialog and you'd like to cancel the closing of the dialog based on whether the form is dirty or not. A bit the use case of the CanDeactivate on the router.
I'd like to provide a PR for this if that's desired. I'd implement this on the cdk-experimental Dialog.
My proposal would be to add a canClose function to the DialogRef. Inside a Dialog one gets the DialogRef injected and could hook on the function onto it, like
import { DialogRef } from '@angular/cdk-experimental/dialog';
...
@Component({...}
export class SomeDialog {
constructor(private dialogRef: DialogRef<any>) {
this.dialogRef.canClose = (/* pass some data? */) => {
// decide whether the dialog can be closed based
// on the current state of SomeDialog component here.
// if it can be closed, return true, otherwise false
}
}
}
On the other side, in the DialogRef implementation here: https://github.com/angular/material2/blob/master/src/cdk-experimental/dialog/dialog-ref.ts#L72-L74
...the current logic could be altered to verify whether such canClose function exists, and if so invoke it.
What do you think? Let me know if this could be a valid option and I'll provide an according PR.
+1
+1. Any news about this?
+1
I'd like to wait with closing the dialog until it's output has been successfully stored in the backend.
My workaround was to subscribe to a rxjs Subject in OnInit hook of the dialog to execute close(). subject.next() then will be fired once the whatever operation is complete
+1
Any news on this? I would love to implement a generic way to prevent closing a dialog containing a dirty form. This would be similar to the unload event when you close the browser.
@marty30 not that clean way, but I try to workaround with something like this:
constructor(
@Inject(MAT_DIALOG_DATA) public data: { type: string, id?: number },
private dialogRef: MatDialogRef<GameBaseComponent>) {
}
ngOnInit(): void {
this.dialogRef.disableClose = true;
this.dialogRef.backdropClick().subscribe(async () => await this.safeClose());
this.createForm();
}
public async safeClose(result?: string): Promise<void> {
if (!this.form.touched && !this.form.dirty) {
this.dialogRef.close();
return;
}
const confirmResult = await this.pageService.confirm({ ... }).afterClosed().toPromise();
if (!Boolean(confirmResult)) {
return;
}
this.dialogRef.close(result);
}
and I change mat-dialog-close with (click)='safeClose()' everywhere in the template too
Anybody has better solution?
Solution for close dialog conditionally.
disable close = true;
closeDialog() {
if (this.profile.form.dirty && confirm('You have unsaved changes! Are you sure you want to continue?')) {
this.dialogRef.close();
}
}
this.dialogRef.keydownEvents().subscribe(key => {
if (key.code === 'Escape') {
this.closeDialog();
}
});
just landed here. interesting read, still open. i bump and will implemented suggestion in the meantime.
Most helpful comment
I'd like to provide a PR for this if that's desired. I'd implement this on the cdk-experimental Dialog.
My proposal would be to add a
canClosefunction to theDialogRef. Inside a Dialog one gets theDialogRefinjected and could hook on the function onto it, likeOn the other side, in the
DialogRefimplementation here: https://github.com/angular/material2/blob/master/src/cdk-experimental/dialog/dialog-ref.ts#L72-L74...the current logic could be altered to verify whether such
canClosefunction exists, and if so invoke it.What do you think? Let me know if this could be a valid option and I'll provide an according PR.