Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material Dialog not closing after navigation

I'm working on an application that shows an overview of entities in a datatable. Every entity has linked entities that are shown as 'xxx linked entities' in a column. When the user clicks on the value of that column, a material dialog opens showing the list of the linked entities. These are all links to other entities. Upon clicking one of these links, the correct page of the entity is shown, but the dialog doesn't close. I does close when using the back button. I am using the closeOnNavigation property.

Some example code:

In my main component:

public openDialog(entity: Entity) {
    const dialogRef = this.dialog.open(EntityDialogComponent, {
        closeOnNavigation: true,
        data: {
            entity,
            otherEntities: this.getNameOfOtherEntities(),
        },
    });
}

Html of the dialog:

<h1 mat-dialog-title>Linked {{otherEntities}}:</h1>
<mat-dialog-content>
<mat-list role="list">
    <mat-list-item role="listitem" *ngFor="let linkedEntity of entity.getProperty('linkedEntities')">
       <a class="m-link m--font-bold" [routerLink]="['/reporting/' + otherEntities, linkedEntity.id]">{{linkedEntity.name}}</a>
    </mat-list-item>
</mat-list>
</mat-dialog-content>
<mat-dialog-actions>
    <button mat-button (click)="cancel()">Close</button>
</mat-dialog-actions>

Dialog component:

@Component({
    selector: "entity-dialog",
    templateUrl: "entity-dialog.component.html",
})
export class EntityDialogComponent {

    public entity: Entity;
    public otherEntities: string;

    constructor(
        public dialogRef: MatDialogRef<EntityDialogComponent>,
        @Inject(MAT_DIALOG_DATA) public data: IDialogData,
    ) {
        this.entity = data.entity;
        this.otherEntities = data.otherEntities;
    }

    public cancel(): void {
        this.dialogRef.close();
    }

}

On the side note:

When I'm on a specific entity page, and I click in a datatable to open a modal and click a link to another entity, the page scrolls to the top, the link in the browser changes to the correct link, but the page doesn't get refreshed for some reason. Any ideas?

like image 208
Bertijn Pauwels Avatar asked Aug 13 '18 11:08

Bertijn Pauwels


People also ask

What is MatDialog?

MatDialog creates modal dialogs that implements the ARIA role="dialog" pattern by default. You can change the dialog's role to alertdialog via MatDialogConfig . You should provide an accessible label to this root dialog element by setting the ariaLabel or ariaLabelledBy properties of MatDialogConfig .

How do I use MatDialog?

Approach: First we need to import 'MatDialog' from '@angular/material/dialog' and we need to create an instance for it in the constructor. Using this instance we can open the dialog box component. Now create a separate component for the dialog and write code as per the requirements.

How to use the angular material dialog?

In order to use the Angular Material Dialog, we will first need to import MatDialogModule: ... ... ... Notice also CourseDialogComponent, this component will be the body of our custom dialog.

How do I use matdialogref to close a dialog?

Components created via MatDialog can inject MatDialogRef and use it to close the dialog in which they are contained. When closing, an optional result value can be provided.

Why is my dialog not closing after ngonchanges?

If you have an error occurring in the ngOnChanges of another component it can cause this un-closable dialog behavior. Show activity on this post. In your example component1 have dialog.open method.

How does matdialog work with tabbable elements?

Once a dialog opens, the dialog will automatically focus the first tabbable element. Because MatDialog instantiates components at run-time, the Angular compiler needs extra information to create the necessary ComponentFactory for your dialog content component.


2 Answers

When you navigate using [routerLink] directive or router.navigate() method of Angular's Router service within the MatDialog, the actual navigation happens. So we can just listen for router's changes and close the dialog.

In your EntityDialogComponent implement ngOnInit as following:

ngOnInit() {
   this._routerSubscription = this._router.events
     .pipe(
       filter((event: RouterEvent) => event instanceof NavigationStart),
       filter(() => !!this.dialogRef)
     )
     .subscribe(() => {
       this.dialogRef.close();
     });
}

The code above closes a dialogRef when NavigationStart event is fired and there is an instance of the dialogRef.

P.S. Make sure that the _routerSubscription is unsunscribed.

like image 171
Andrei Mihalciuc Avatar answered Oct 03 '22 18:10

Andrei Mihalciuc


you can use this matDialogClose attribute.

<button mat-button matDialogClose>Cancel</button>
like image 37
farhan siddiqui Avatar answered Oct 03 '22 17:10

farhan siddiqui