How to close child/nested dialog using matDialogClose instead of parent dialog

Viewed 1350

I am having a two dialogs with a sort of parent-child relationship. Parent is a standalone dialog component while child is created from ng-template

Now, the problem is, that if I use matDialogClose inside ng-template parent dialog is closed, and child is intact.

Here is a stackblitz for you https://stackblitz.com/edit/mat-dialog-example-vbxhc3

Main dialog template

<ng-template #nested>
    hey, i am nested dialog, close me with the button
    <button matDialogClose="someResult">CLOSE ME </button>
</ng-template>

opening child template

  @ViewChild("nested")
  nestedTmplateRef;
  private dialog:MatDialog
  ...
   this.dialog.open(this.nestedTmplateRef);

Can I close child dialog using matCloseDialog directive?? I am interested in using this solution as other obvious workarounds like controlling child dialog from component is know to me. However, using just directive would save me some boilerplace code. I am little bit rusty with angular material components and probably I dont see a obvious solution.

1 Answers

That seems to be a bug in material. If you check the code here you can see the comment:

When this directive is included in a dialog via TemplateRef (rather than being in a Component), the DialogRef isn't available via injection because embedded views cannot be given a custom injector. Instead, we look up the DialogRef by ID. This must occur in onInit, as the ID binding for the dialog container won't be resolved at constructor time.

However, when using a nested dialog, the method getClosestDialog does not seem to get the correct dialog.

I've made a sort of workaround for it though, and perhaps you can create a custom directive from this logic to make it reusable:

By adding a reference on the MatDialogClose and querying this in your component you can set the correct dialog reference:

<ng-template #nested>
  hey, i am nested dialog, close me with the button
  <button matDialogClose="someResult" #innerClose="matDialogClose">CLOSE ME </button>
</ng-template>
@ViewChild("nested")
nestedTmplateRef;

@ViewChild('innerClose')
close: MatDialogClose;

ngOnInit(){
  const ref = this.dialog.open(this.nestedTmplateRef);  

  // have to wait for the next tick so the `dialogRef` does not get overwritten again
  setTimeout(() => this.close.dialogRef = ref);
}

working stackblitz

Related