在浏览器后面关闭Angular Material对话框

Bri*_*man 10 angular-material angular

我正在使用Angular Material(5.0.0)为移动设备创建单页Web应用程序.我有一个需要显示对话框的场景.我想允许用户回击关闭对话框,因为这是在移动设备上非常常见的行为(特别是在Android上).

当前发生这种情况时,页面将转到上一页.我需要按钮才能简单地关闭对话框.

关于如何实现这一点的任何想法?

Mur*_*sli 14

此选项已经可用

let dialogRef = dialog.open(DialogExample, {
  height: '400px',
  width: '600px',
  closeOnNavigation: true
});
Run Code Online (Sandbox Code Playgroud)

使用路由更改事件的其他方式:

1.从应用组件

  constructor(router: Router, matDialog: MatDialog) {

    // Close any opened dialog when route changes
    router.events.pipe(
      filter((event: RouterEvent) => event instanceof NavigationStart),
      tap(() => this.matDialog.closeAll())
    ).subscribe();
  }
Run Code Online (Sandbox Code Playgroud)

2.从对话框组件

@Component({
  selector: 'example-dialog',
  templateUrl: 'example-dialog.html',
})
export class ExampleDialog {

  constructor(
    public dialogRef: MatDialogRef<ExampleDialog>,
    router: Router
  ) {

    // Close dialog ref on route changes
    router.events.pipe(
      filter((event: RouterEvent) => event instanceof NavigationStart),
      tap(() => this.dialogRef.close()),
      take(1),
    ).subscribe();
  }

}
Run Code Online (Sandbox Code Playgroud)

  • 我不相信这回答了这个问题。我知道后退按钮应该关闭对话框*而不是*导航回来。我认为这些示例只会关闭对话框不会阻止导航? (6认同)
  • @ZNS我回答了这个问题,但也许你应该问“如何关闭浏览器的后退导航”,可能有一种有角度的方法来做到这一点,当你获得该功能时,只需注入对话框服务并使用 `matDialog.closeAll( )` (3认同)

Vas*_*zos 10

关于下面的解决方案,我受到了@valeriy-katkov答案的启发,进行了改进和简化。

1.配置对话框在导航时不关闭

关闭导航

this.dialog.open(Component, {
      ...
      closeOnNavigation: false
    });
Run Code Online (Sandbox Code Playgroud)

2. 将CanActivateChild Guard 添加到根路由。

路由配置:

const rootRoutes: Routes = [{
    path: '',
    canActivateChild: [ CanActivateChildGuard ],
    children: [
        ...
    ]
}];
Run Code Online (Sandbox Code Playgroud)

3. 如果打开了对话框,守卫将取消浏览器返回上的导航,并关闭对话框。

简单的守卫:

export class CanActivateChildGuard implements CanActivateChild {
    constructor(private dialog: MatDialog) {}

    canActivateChild(): boolean {
        if (this.dialog.openDialogs.length > 0) {
            this.dialog.closeAll();
            return false;
        } else {
            return true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Val*_*kov 6

作为一种解决方法,您可以将CanActivateChild 防护添加到根路由。如果对话框打开并关闭对话框,守卫将取消导航。

路由配置:

const rootRoutes: Routes = [{
    path: '',
    canActivateChild: [ CanActivateChildGuard ],
    children: [
        ...
    ]
}];
Run Code Online (Sandbox Code Playgroud)

还有守卫:

export class CanActivateChildGuard implements CanActivateChild {
    constructor(
        private readonly router: Router,
        private readonly location: Location
    ) {}

    canActivateChild(route: ActivatedRouteSnapshot): boolean {
        if (this.dialog.openDialogs.length > 0) {
            // fix navigation history, see github issue for more details
            // https://github.com/angular/angular/issues/13586
            const currentUrlTree = this.router.createUrlTree([], route);
            const currentUrl = currentUrlTree.toString();
            this.location.go(currentUrl);

            this.dialog.closeAll();
            return false;
        } else {
            return true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ara*_*ind 2

您可以注入MatDialog服务并调用closeAll方法来关闭所有打开的对话框,如下所示,

constructor(public dialog: MatDialog) {
         this.dialog.closeAll();
}
Run Code Online (Sandbox Code Playgroud)

现场演示

  • 我可能没说清楚。我在我的组件上,比如说 MainComponent。用户执行一些操作来启动对话框。用户点击(浏览器)返回以取消对话框。当前,路由器正在处理 URL 的更改并显示先前的组件(并且还关闭对话框)。我希望它们保留在 MainComponent 上(不更改组件)并简单地关闭对话框。我想要完成此任务,我需要有一个对话框来说明如何更改 URL,以便浏览器将 URL 更改回原始组件 URL,但不确定如何更改。 (4认同)