如何在按下回车键时阻止Angular Material的 select组件打开?
我在一个 mat-dialog 里面有一个表单,我希望在按下回车键且表单有效时让对话框“提交”,也就是关闭对话框并将表单的值传递给对话框的 afterClose Promise。
不巧的是,我的表单由若干个 mat-select 构成,它们会劫持回车键并用它来打开各自的下拉菜单,我希望不要发生这种情况,但在Material文档中我似乎找不到关闭它的方法(顺便说一句,我还想保留控件其余部分的键盘导航功能)。
我现在为这些下拉框附加一个 keydown 事件处理程序,它会同时检查是否按下回车键以及表单是否有效;如果有效,就使用对话框引用来关闭对话框。
然而,这仍然会在对话框关闭前短暂地打开下拉框。如果表单无效,它也会打开。如何阻止这种行为?
<form mat-dialog-content
[formGroup]="formGroup">
<mat-form-field appearance="fill">
<mat-label>Sprache</mat-label>
<mat-select formControlName="language"
(keydown)="submitOnEnter($event)"
[panelClass]="colorClass()">
@for (language of languages(); track language.id) {
<mat-option [value]="language">{{language.title}}</mat-option>
}
</mat-select>
</mat-form-field>
<!-- There's some more mat-selects following but I'll avoid repetition -->
</form>
<div mat-dialog-actions>
<button mat-button
(click)="close()">Abbrechen</button>
<button mat-raised-button
[mat-dialog-close]="formGroup.value"
[disabled]="!formGroup.valid">OK</button>
</div>
以及组件的相关部分:
export class WordDialog implements OnInit {
protected _dialogRef: MatDialogRef<WordDialog> = inject(WordDialog);
public readonly languages: WritableSignal<DataEntry[]> = signal([]);
public formGroup: FormGroup = new FormGroup({ language: new FormControl<DataEntry | undefined>(undefined, Validators.required), /* Some more controls */ });
ngOnInit(): void {
// this.languages get set here but how is irrelevant.
}
public close(): void {
this._dialogRef.close();
}
public submitOnEnter(event: KeyboardEvent): void {
if (event.key === 'Enter') {
event.preventDefault(); // Probably irrelevant, does not prevent select dropdown.
if (this.formGroup.valid) {
this._dialogRef.close(this.formGroup.value);
}
}
}
}
解决方案
你可以使用 addEventListener,将 capture 设为 true,以确保你的监听器在 mat-select 正在使用它之前就被调用,然后阻止传播:
private readonly selectElements = viewChildren(MatSelect, {
read: ElementRef,
});
private readonly selects = viewChildren(MatSelect);
ngAfterViewInit() {
const selects = this.selects();
this.selectElements().forEach((select, i) => {
(select.nativeElement as HTMLElement).addEventListener(
'keydown',
(event: KeyboardEvent) => {
if (
event.key === 'Enter' &&
!selects[i].panelOpen &&
this.formGroup.valid
) {
event.stopPropagation();
this._dialogRef.close(this.formGroup.value);
}
},
{ capture: true }
);
});
}
完整示例
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。