Angular Material 导航后对话框未关闭

Angular Material Dialog not closing after navigation

我正在开发一个显示数据表中实体概览的应用程序。每个实体都有 link 个实体,在一列中显示为 'xxx linked entities'。当用户单击该列的值时,将打开一个 material 对话框,显示 linked 实体的列表。这些都是 link 给其他实体的。单击这些 link 之一后,会显示实体的正确页面,但对话框不会关闭。使用后退按钮时我确实关闭了。我正在使用 closeOnNavigation 属性.

一些示例代码:

在我的主要组件中:

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

Html:

<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>

对话框组件:

@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();
    }

}

旁注:

当我在特定实体页面上时,我在数据表中单击以打开模式并单击 link 到另一个实体,页面滚动到顶部,link在浏览器中更改为正确的 link,但由于某种原因页面没有刷新。 有什么想法吗?

您好,根据文档,它说:closeOnNavigation:当用户进入历史 backwards/forwards 时对话框是否应关闭。

历史导航通常是指浏览器后退和前进按钮:https://developer.mozilla.org/en-US/docs/Web/API/History_API

然而,在您的场景中,您可以做的不是直接从 html 进行路由,而是创建一个函数,该函数将在对话框关闭后进行路由,这样您就可以确保在启动之前先关闭对话框你的导航。

   <a class="m-link m--font-bold" (mousedown)="navigateToEntity($event)">{{linkedEntity.name}}</a>

在你的组件里面有类似

的东西
  navigateToEntity(event) {
    this.dialogRef.afterClosed.pipe(
      tap(() => this.router.navigate(['navigate to wherever'])),
      first()
    ).subscribe();
    this.dialogRef.close();
  }

希望这会有所帮助,我没有使用 Material 组件,但阅读了一些文档,这就是我实现它的方式。

当您在 MatDialog 中使用 [routerLink] 指令或 Angular 路由器服务的 router.navigate() 方法进行导航时,实际的导航就会发生。所以我们可以只监听路由器的变化并关闭对话框。

在您的 EntityDialogComponent 中实现 ngOnInit 如下:

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

NavigationStart 事件被触发并且存在 dialogRef 的实例时,上面的代码关闭了 dialogRef

P.S。确保 _routerSubscription 未被注销。

我遇到了这个问题,现在刚刚解决了。

您需要在创建 dialogRef 对象后订阅路由器事件。你可以查看代码

const dialogRef = this.dialog.open(MyComponent, {
  width: '380px',
  height: '320px',
});
this.router.events
 .subscribe(() => {
   dialogRef.close();
 });

没有错误或警告,但 closeOnNavigation: true 只有在使用对话框将这些提供程序添加到模块后才开始为我工作:

import { Location, LocationStrategy, PathLocationStrategy, APP_BASE_HREF } from "@angular/common";

...
    providers: [
        Location,
        { provide: LocationStrategy, useClass: PathLocationStrategy },
        { provide: APP_BASE_HREF, useValue: '/' }
    ]
...

我怀疑在我的情况下,这是因为使用 UI-Router 并且之前从未初始化内置 Angular 路由器。

您可以使用此 matDialogClose 属性。

<button mat-button matDialogClose>Cancel</button>