如何在Angular Material中将Tab键作为Enter键?

时间:2019-03-14 06:52:22

标签: html angular events autocomplete angular-material

这是我的角物料自动完成代码

<input type="search" id="setId" name="setId" [attr.list]='collectionType' [(ngModel)]="selValue" class="text-box"
  placeholder="--Select--" (focus)="ValidateParent()" (keyup.tab)="test()" (keyup)="EmitValues($event)" [id]="setId"
  [matAutocomplete]="auto" [title]="selValue" [placeholder]='WaterMarkText'>


<div [hidden]="IsCascading">
  <mat-autocomplete [id]="collectionType" #auto="matAutocomplete" (optionSelected)='onChange($event)'>
    <mat-option *ngFor="let items of codeList" [value]="items.text" [attr.data-text]='items.text' [id]="items.value">
      {{items.text}}
    </mat-option>
  </mat-autocomplete>
</div>

角度材料在选择tab时遇到问题,例如,在单击tab按钮时,物料自动完成功能无法选择该值。但在单击enter按钮时仍然可以使用。因此,我需要手动为enter键事件覆盖tab键事件。怎么可能?

2 个答案:

答案 0 :(得分:2)

改善我的评论,并根据响应我们可以创建指令

import { Directive, AfterViewInit, OnDestroy, Optional } from '@angular/core';
import { MatAutocompleteTrigger } from '@angular/material';


@Directive({ selector: '[tab-directive]' })
export class TabDirective implements AfterViewInit, OnDestroy {
  observable: any;
  constructor(@Optional() private autoTrigger: MatAutocompleteTrigger) { }
  ngAfterViewInit() {
    this.observable = this.autoTrigger.panelClosingActions.subscribe(x => {
      if (this.autoTrigger.activeOption) {
        this.autoTrigger.writeValue(this.autoTrigger.activeOption.value)
      }
    })
  }
  ngOnDestroy() {
    this.observable.unsubscribe();
  }
}

您使用:

<input tab-directive type="text" matInput [formControl]="myControl" 
      [matAutocomplete]="auto" >

(请参阅stackblitz

答案 1 :(得分:1)

我参加聚会有点晚了;因此,Eliseo 的回答存在一个令人讨厌的问题:即使用户已经通过单击鼠标从面板中选择了不同的选项,它也会自动完成。我最终想出的解决方法一点也不简单。

    /**
     * Selects currently active item on TAB
     * @example
     * <input vxTabActiveOption [matAutocomplete]="matAutocomplate">
     * <mat-autocomplete #matAutocomplate="matAutocomplete" autoActiveFirstOption>
     */
    @Directive({ selector: '[vxTabActiveOption]' })
    export class TabActiveOptionDirective implements AfterViewInit, OnDestroy {
      private readonly destroy$ = new Subject<never>();
    
      /**
       * Whether or not the autocomplete panel was open before the event
       */
      private panelOpen = false;
    
      constructor(
        private autoTrigger: MatAutocompleteTrigger,
        private control: NgControl
      ) { }
    
      ngAfterViewInit() {
        const autocomplete = this.autoTrigger.autocomplete;
        merge(
          autocomplete.opened.pipe(map(() => true)),
          autocomplete.closed.pipe(map(() => false))
        ).pipe(
          takeUntil(this.destroy$),
          delay(0)
        ).subscribe(value => this.panelOpen = value);
      }

      @HostListener('keydown.tab')
      onBlur() {
        if (this.panelOpen && this.autoTrigger.activeOption) {
          const value = this.autoTrigger.activeOption.value;
          this.control.control.setValue(value, { emit: false });
          this.autoTrigger.writeValue(value);
        }
      }
    
      ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
      }
    }