Angular:使用 mat-select 时,有没有办法在按 SPACE 按钮时不选择焦点项目?

zhi*_*nee 4 angular-material angular mat-select mat-option

通过查看,https://v5.material.angular.io/components/select/overview
有几种键盘交互。

  • 键盘交互
  • DOWN_ARROW:聚焦下一个选项
  • UP_ARROW:聚焦上一个选项
  • ENTER 或 SPACE:选择焦点项目

我能够停止整个交互,但我想要的是:
保留所有键盘交互,除了空格键

有办法做到吗?
谢谢。

Eli*_*seo 8

考虑一下乔治联合国的回答

但如果有一个很好的理由,你总是可以“重写”该函数。

在您的选择中使用模板引用变量

<mat-select #select="matSelect">
   ...
</mat-select>
Run Code Online (Sandbox Code Playgroud)

并且可以使用ViewChild来获取mat select并重写该函数

  @ViewChild('select', { static: true }) select: any;

  ngOnInit() {
    this.select._handleKeydown = (event: KeyboardEvent) => {
      if (event.keyCode==SPACE)
        return
      if (!this.select.disabled) {
        this.select.panelOpen
          ? this.select._handleOpenKeydown(event)
          : this.select._handleClosedKeydown(event);
      }
    };
  }
Run Code Online (Sandbox Code Playgroud)

注意:空间定义在

import { SPACE} from '@angular/cdk/keycodes';
Run Code Online (Sandbox Code Playgroud)

更新我们也可以使用指令

@Directive({
  selector: '[no-space]',
})
export class NoSpaceDirective {
  @Output('spacekeydown') spacekeydown: EventEmitter<any> =
    new EventEmitter<any>();
    
constructor(@Self() private select: MatSelect) {
    this.select._handleKeydown = (event: KeyboardEvent) => {
      if (event.keyCode == SPACE) {
          const active=this.select.panelOpen?
                 this.select.options.filter(x=>x.active)[0]|| null:
                 null
        this.spacekeydown.emit(active?active.value:null);
      } else {
        if (!this.select.disabled) {
          this.select.panelOpen
            ? (this.select as any)._handleOpenKeydown(event)
            : (this.select as any)._handleClosedKeydown(event);
        }
      }
    };
  }

}
Run Code Online (Sandbox Code Playgroud)

你用作为

<mat-select no-space 
     (spacekeydown)="doSomething($event)">
   ...
</mat-select>
Run Code Online (Sandbox Code Playgroud)

一如既往,如果我们使用“选择器”来代替[no-space] mat-select

@Directive({
  selector: 'mat-select',
})
...
Run Code Online (Sandbox Code Playgroud)

该指令适用于我们所有的 mat-select

查看带有指令的stackblitz


ake*_*lec 8

我认为这是相关的,对于有输入字段并且需要在用户按下输入中的空格时mat-select禁用关闭的人来说可能会感兴趣。mat-select您只需要防止单击和按键时的默认行为:

<mat-select>
    <mat-option
        <input 
            (click)="$event.stopPropagation()"
            (keydown)="$event.stopPropagation()">
        </input>
    </mat-option>
</mat-select>
Run Code Online (Sandbox Code Playgroud)