MatDialog 服务可用于打开具有 Material Design 样式和动画效果的模态对话框。

通过调用 open 方法并传要加载的组件和可选的配置对象可以打开对话框。 open 方法将返回一个 MatDialogRef 的实例:

let dialogRef = dialog.open(UserProfileComponent, {
  height: '400px',
  width: '600px',
});

MatDialogRef 提供了已打开对话框的一个引用。可用它来关闭对话框和接受关闭对话框后的通知。 当该对话框关闭时,任何一个通知用的 Observable 都会结束(complete)。

dialogRef.afterClosed().subscribe(result => {
  console.log(`Dialog result: ${result}`); // Pizza!
});

dialogRef.close('Pizza!');

通过 MatDialog 创建的组件可以注入 MatDialogRef,并用它来关闭包含该组件的对话框。 当关闭时,可以提供一个可选的结果值。该结果值会作为结果转发给 afterClosed 事件。

@Component({/* ... */})
export class YourDialog {
  constructor(public dialogRef: MatDialogRef<YourDialog>) { }

  closeDialog() {
    this.dialogRef.close('Pizza!');
  }
}

对话框的默认选项可以通过在应用根模块中为 MAT_DIALOG_DEFAULT_OPTIONS 令牌提供一个 MatDialogConfig 实例来指定。

@NgModule({
  providers: [
    {provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: {hasBackdrop: false}}
  ]
})

如果要和对话框共享数据,可以通过 data 选项把信息传给该组件。

let dialogRef = dialog.open(YourDialog, {
  data: { name: 'austin' },
});

要在对话框组件中访问此数据,可以使用依赖注入令牌 MAT_DIALOG_DATA

import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA} from '@angular/material/dialog';

@Component({
  selector: 'your-dialog',
  template: 'passed in {{ data.name }}',
})
export class YourDialog {
  constructor(@Inject(MAT_DIALOG_DATA) public data: {name: string}) { }
}

注意,如果你正在使用模板对话框(用 TemplateRef 打开的对话框),其数据在模板中是隐式可用的:

<ng-template let-data>
  Hello, {{data.name}}
</ng-template>

下面几个指令能让你更轻松地定义对话框内容的结构:

名称 描述
mat-dialog-title [Attr] 对话框标题,应用于标题元素(例如 <h1><h2>
<mat-dialog-content> 对话框的主要可滚动内容。
<mat-dialog-actions> 对话框底部操作按钮的容器。按钮对齐方式可以通过 align 属性控制,该属性可以设置为 endcenter
mat-dialog-close [Attr] 添加到 <button> 上,使按钮关闭对话框,并可选地从绑定值中获取结果。

例如:

<h2 mat-dialog-title>Delete all elements?</h2>
<mat-dialog-content>This will delete all elements that are currently on this page and cannot be undone.</mat-dialog-content>
<mat-dialog-actions>
  <button mat-button mat-dialog-close>Cancel</button>
  <!-- The mat-dialog-close directive optionally accepts a value as a result for the dialog. -->
  <button mat-button [mat-dialog-close]="true">Delete</button>
</mat-dialog-actions>

一旦打开了对话框,它就会自动把焦点转给第一个可接受焦点的元素。

你可以通过 tabindex 属性来控制哪个元素可以接受焦点。

<button mat-button tabindex="-1">Not Tabbable</button>

你可以使用 enterAnimationDurationexitAnimationDuration 选项控制对话框的进入和退出动画的持续时间。如果要完全禁用对话框的动画,可以通过将这些属性设置为 0ms 来实现。

MatDialog 会创建默认实现了 ARIA role="dialog" 模式的模态对话框。你可以通过 MatDialogConfig 来把对话框的 role 改为 alertdialog

你应该通过设置 MatDialogConfigariaLabelariaLabelledBy 属性来为这个根对话框元素提供一个无障碍标签。你还可以通过 MatDialogConfigariaDescribedBy 属性来指定描述元素 ID。

默认情况下,esc 键会关闭 MatDialog 。虽然你可以通过 MatDialogConfigdisableClose 属性禁用此行为,但这样做会破坏 ARIA role="dialog" 模式的预期交互模式。

打开时,MatDialog 会捕获浏览器焦点,使其无法逃脱 role="dialog" 的根元素。默认情况下,对话框中的第一个可 tab 到的元素获得焦点。你可以使用 MatDialogConfigautoFocus 属性自定义哪个元素获得焦点,该属性支持以下值。

行为
first-tabbable 将焦点设置到第一个可获得焦点的元素。这是默认设置。
first-header 将焦点设置到第一个标题元素( role="heading"h1h6
dialog 将焦点设置到根 role="dialog" 元素。
任何 CSS 选择器 将焦点设置到与给定选择器匹配的第一个元素。

虽然默认设置是适用于大多数应用程序的最佳行为,但特殊情况下也可能会需要这些替代方案。始终测试你的应用程序以验证最适合你的用户的行为。

当关闭时, MatDialog 会将焦点恢复到先前在对话框打开时持有焦点的元素。但是,如果先前聚焦的元素已不存在了,则必须添加额外的处理以将焦点返回到对用户工作流程有意义的元素。从菜单打开对话框是导致这种情况的常见模式之一。单击菜单项时菜单就会关闭,因此当底部工作表尝试恢复焦点时,聚焦的菜单项已不存在于 DOM 中。

你可以使用来自 MatDialogRefafterClosed() observable 来添加对这种情况的处理。