导航后未关闭“角度材质”对话框

时间:2018-08-13 11:53:59

标签: angular angular-material material-design angular2-routing material

我正在开发一个显示数据表中的实体概述的应用程序。每个实体都有链接的实体,这些实体在列中显示为“ xxx链接的实体”。当用户单击该列的值时,将打开一个材料对话框,显示链接实体的列表。这些都是到其他实体的链接。单击这些链接之一后,将显示该实体的正确页面,但该对话框不会关闭。使用后退按钮时,我确实关闭。我正在使用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();
    }

}

在旁注:

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

5 个答案:

答案 0 :(得分:3)

在MatDialog中使用Angular路由器服务的[routerLink]指令或router.navigate()方法导航时,实际的导航发生了。这样我们就可以侦听路由器的更改并关闭对话框。

在您的EntityDialogComponent中,按以下方式实现ngOnInit:

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

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

P.S。确保未取消_routerSubscription

答案 1 :(得分:2)

您可以使用此 matDialogClose 属性。

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

答案 2 :(得分:1)

根据文档显示的嗨:closeOnNavigation:当用户向后/向前浏览历史记录时,对话框是否应该关闭。

历史记录导航通常表示浏览器的后退和前进按钮: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 Components并没有太多合作,但是通读了一些文档,这就是我将如何实现它。

让我知道这是否有帮助!

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

没有错误或警告,但是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路由器。