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>
我正在开发一个显示数据表中实体概览的应用程序。每个实体都有 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>