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 属性控制,该属性可以设置为
end 和
center 。 |
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>
你可以使用 enterAnimationDuration
和 exitAnimationDuration
选项控制对话框的进入和退出动画的持续时间。如果要完全禁用对话框的动画,可以通过将这些属性设置为 0ms
来实现。
MatDialog
会创建默认实现了 ARIA role="dialog"
模式的模态对话框。你可以通过 MatDialogConfig
来把对话框的 role
改为 alertdialog
。
你应该通过设置 MatDialogConfig
的 ariaLabel
或 ariaLabelledBy
属性来为这个根对话框元素提供一个无障碍标签。你还可以通过 MatDialogConfig
的 ariaDescribedBy
属性来指定描述元素 ID。
默认情况下,esc 键会关闭 MatDialog
。虽然你可以通过 MatDialogConfig
的 disableClose
属性禁用此行为,但这样做会破坏 ARIA role="dialog"
模式的预期交互模式。
打开时,MatDialog
会捕获浏览器焦点,使其无法逃脱 role="dialog"
的根元素。默认情况下,对话框中的第一个可 tab 到的元素获得焦点。你可以使用 MatDialogConfig
的 autoFocus
属性自定义哪个元素获得焦点,该属性支持以下值。
值 | 行为 |
---|---|
first-tabbable |
将焦点设置到第一个可获得焦点的元素。这是默认设置。 |
first-header |
将焦点设置到第一个标题元素(
role="heading" ,
h1 到
h6 ) |
dialog |
将焦点设置到根
role="dialog" 元素。 |
任何 CSS 选择器 | 将焦点设置到与给定选择器匹配的第一个元素。 |
虽然默认设置是适用于大多数应用程序的最佳行为,但特殊情况下也可能会需要这些替代方案。始终测试你的应用程序以验证最适合你的用户的行为。
当关闭时, MatDialog
会将焦点恢复到先前在对话框打开时持有焦点的元素。但是,如果先前聚焦的元素已不存在了,则必须添加额外的处理以将焦点返回到对用户工作流程有意义的元素。从菜单打开对话框是导致这种情况的常见模式之一。单击菜单项时菜单就会关闭,因此当底部工作表尝试恢复焦点时,聚焦的菜单项已不存在于 DOM 中。
你可以使用来自 MatDialogRef
的 afterClosed()
observable 来添加对这种情况的处理。