【问题标题】:Angular - How to jump from an input to another?Angular - 如何从一个输入跳到另一个?
【发布时间】:2020-07-30 02:22:20
【问题描述】:

我想绑定箭头键的事件以跳转到 MatTable 中的另一个输入。

我想做类似以下情况的事情:

我的组件.html

<table mat-table [dataSource]="dataSource">
    <ng-container matColumnDef="name">
        <th th mat-header-cell *matHeaderCellDef>Name</th>
        <td mat-cell *matCellDef="let element">
            <input type="text" (keyup.arrowup)="jumpToPreviousNameInput()" (keyup.arrowdown)="jumpToNextNameInput()" (keyup.arrowright)="jumpToAgeInput()"/>
        </td>
    </ng-container>
    
    <ng-container matColumnDef="age">
        <th mat-header-cell *matHeaderCellDef>Age</th>
        <td mat-cell *matCellDef="let element">
            <input type="number" min="0" (keyup.arrowup)="jumpToPreviousAgeInput()" (keyup.arrowdown)="jumpToNextAgeInput()" (keyup.arrowleft)="jumpToNameInput()" />
        </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns; let element" class="table-row" </tr>
</table>

Angular 9 可以做到这一点吗?

我不知道如何在 Angular 中获取下一个输入元素。在 Vanilla JS 中,我会执行以下操作:

let myTable = document.querySelector('table')

let inputs = myTable.querySelectorAll('input')

inputs.forEach((input, index) => {

    input.addEventListener('keydown', e => {
        const key = e.key;

        switch(key) {

            case "ArrowLeft":
                try { inputs[index-1].focus() } catch {}
                break;

            case "ArrowRight":
                try { inputs[index + 1].focus() } catch { }
                break;

            case "ArrowUp":
                try { inputs[index - 2].focus() } catch { }
                break;
            
            case "ArrowDown":
                try { inputs[index + 2].focus() } catch { }
                break;

        }
    })

})

【问题讨论】:

标签: angular angular-material mat-table


【解决方案1】:

这可以通过@angular/cdk 中的ListKeyManager 轻松完成。 @angular/cdk 有很多核心的基本功能。在这里,我分享一个简单的代码。您必须相应地对其进行更改。

import { Component, ViewChild, ViewChildren, ElementRef, QueryList, HostListener, AfterViewInit } from '@angular/core';
import { FocusTrapFactory, FocusMonitor, ListKeyManager} from '@angular/cdk/a11y'

@Component({
  selector: 'app-root',
  template: `
  <button (click)="testA11y()"> Test A11y! </button>
  <div #element role="dialog" hidden=true>
      <label>Sample field</label>
      <input #elementChild>
      <label>Sample field</label>
      <input #elementChild>
      <label>Sample field</label>
      <input #elementChild>
      <label>Sample field</label>
      <input #elementChild>
      <label>Sample field</label>
      <input #elementChild>
  </div>`
})
export class AppComponent implements AfterViewInit {

  keyManager : any

  @ViewChild('element') element : ElementRef; 
  @ViewChildren('elementChild') elementChild : QueryList<any>

  constructor( private focusTrap: FocusTrapFactory, 
            private focusMonitor : FocusMonitor ) {}

  ngAfterViewInit() { 
    this.keyManager = new ListKeyManager(this.elementChild) 
    this.keyManager.withHorizontalOrientation('ltr') // Arrow navigation options 
    this.keyManager.withWrap()  // Arrow navigation options 
  }

  /* Enables keyboard arrows navigation */
  @HostListener('window:keyup', ['$event']) 
  keyFunc(event) {
    if (event.code !== 'Tab') {
      this.keyManager.onKeydown(event)
      this.focusMonitor.focusVia(this.keyManager.activeItem.nativeElement, "keyboard")
    }
    else {  // 'artificially' updates the active element in case the user uses Tab instead of arrows
      this.keyManager.onKeydown(event)
      this.keyManager.setNextItemActive()
    }
  }

  /* Shows the form, puts focus on it and initialize keyboard navigation */
  testA11y() {
    this.element.nativeElement.hidden = false;   
    let focusTrap = this.focusTrap.create(this.element.nativeElement)  // creates a focus trap region
    focusTrap.focusInitialElement()     // Moves the focus in the form (by default the first field)
    this.keyManager.setFirstItemActive()    // Sets the element we focused on as 'active' to the KeyManager
  }

}

上面也有一些不错的文章https://moduscreate.com/blog/adding-keyboard-navigation-to-angular-lists-using-angular-cdk-listkeymanager/(注意:-不是我写的)

【讨论】:

    猜你喜欢
    • 2016-10-30
    • 2012-06-20
    • 2014-10-27
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    相关资源
    最近更新 更多