向下箭头和向上箭头键在角度

问题描述 投票:0回答:2

我在这里分享我的代码,当我第一次按向下箭头键时,它将进入下一行,但再次按向下箭头键时,它将无法正常工作

(https://i.stack.imgur.com/4qznx.jpg)

**HTML**
<mat-row *matRowDef="let row; columns: displayedColumns; let index = 'index+1';" 
         class="table-row" 
         (click)="getRecordFromTable(row, index)" 
         tabindex="999" 
         (keydown.arrowdown)="arrowUpDownEvent(index,true)"
         (keydown.arrowup)="arrowUpDownEvent(index,false)" 
         (keydown.enter)="onConfirmButton(row,index)" 
         [ngClass]="{'previous-highlighted':    
         (this._POSFormService.POSHeaderForm.get('walkInCustomerCode')?.value == row.code), 'current-
          highlighted': (this.customerFormService.selectedCustomerCode.value == row.code && 
          this._POSFormService.POSHeaderForm.get('walkInCustomerCode')?.value !== row.code)}">
</mat-row>

**TS**
arrowUpDownEvent(index: number,isDownArrow : boolean) { 
if (isDownArrow){ 
     let nextrow = this.customerFilterDataSource.data[index]; 
if (nextrow){ 
     this.getRecordFromTable(nextrow, index + 1);
 } 
}
else{ 
   let nextrow = this.customerFilterDataSource.data[index-2]; 
   if(nextrow){ 
        this.getRecordFromTable(nextrow, index - 2);
 } 
} 
} 
angular keydown angular-material-table
2个回答
0
投票
// Define a variable to keep track of the currently focused row index
focusedRowIndex: number = -1;

arrowUpDownEvent(index: number, isDownArrow: boolean) {
  if (isDownArrow) {
    // Move focus to the next row if available
    if (index < this.customerFilterDataSource.data.length - 1) {
      this.focusedRowIndex = index + 1;
    }
  } else {
    // Move focus to the previous row if available
    if (index > 0) {
      this.focusedRowIndex = index - 1;
    }
  }
}

// In your HTML template, bind the focusedRowIndex to each row's tabindex and classes
<mat-row *matRowDef="let row; columns: displayedColumns; let index = index;"
         class="table-row"
         (click)="getRecordFromTable(row, index)"
         [tabindex]="focusedRowIndex === index ? '999' : null"
         (keydown.arrowdown)="arrowUpDownEvent(index, true)"
         (keydown.arrowup)="arrowUpDownEvent(index, false)"
         (keydown.enter)="onConfirmButton(row, index)"
         [ngClass]="{
           'previous-highlighted': this._POSFormService.POSHeaderForm.get('walkInCustomerCode')?.value == row.code,
           'current-highlighted': this.customerFormService.selectedCustomerCode.value == row.code && this._POSFormService.POSHeaderForm.get('walkInCustomerCode')?.value !== row.code,
           'focused-row': focusedRowIndex === index
         }">
</mat-row>

0
投票

之前的代码没有“集中”,否则改变类。

为了聚焦,我们需要“到达”HTMLElement。为此,您使用模板引用变量和 ViewChildren

<tr mat-row  #row tabIndex="1" 
    *matRowDef="let row; columns: displayedColumns;let index=index"
      (keydown.arrowdown)="arrowUpDownEvent(index, 1)" 
      (keydown.arrowup)="arrowUpDownEvent(index, -1)">
</tr>

在.ts中

  //declare a QueryList of ElementRef

  @ViewChildren('row',{read:ElementRef}) rows!:QueryList<ElementRef>

  //I choose pass to the function 1 or -1 to simply the code
  arrowUpDownEvent(index:number,incr:number)
  {
    index+=incr;
    if (index>=this.rows.length || index<0)
      return
    const row=this.rows.find((_x:ElementRef,i:number)=>i==index)
                         ?.nativeElement.focus()
  }

我们可以采取另一种方法,即使用 rxjs fromEvent 运算符“监听” document.keydown

  @ViewChildren('row',{read:ElementRef}) rows!:QueryList<ElementRef>
  keyUpDown!: Subscription; //<--declare a subscription

  ngOnInit() {
    //we are interesting only when arrow up (38) and arrow down (40)
    this.keyUpDown = fromEvent(document, 'keydown')
      .pipe(filter((x: any) => x.keyCode == 40 || x.keyCode == 38))
      .subscribe((res) => {
        //get the active element
        const activeRow = document.activeElement;

        //look for in all the "rows" if is the active element
        // or if contains the active element

        let row = activeRow
          ? this.rows.find(
              (x: ElementRef) =>
                x.nativeElement == activeRow ||
                x.nativeElement.contains(activeRow)
            )
          : null;

        //we do nothing if the row is the last/first and key down/up
        if (
          (res.keyCode == 38 && row == this.rows.first) ||
          (res.keyCode == 40 && row == this.rows.last)
        )
          return;

        //if not find start at first or at last
        if (row == null)
          row = res.keyCode == 38 ? this.rows.last : this.rows.first;
        else {  //is the focus is really in one row
          if (row.nativeElement == document.activeElement) {
            const rowIndex =
              this.rows
                .toArray()
                .findIndex((x) => x.nativeElement == activeRow) +
              (res.keyCode == 38 ? -1 : 1);
 
            //find the row to put the focus
            row = this.rows.find((x: ElementRef, i: number) => i == rowIndex);
          }
        }
        row.nativeElement.focus();
      });
  }

  //don't forget unsubscribe
  ngOnDestroy() {
    this.keyUpDown && this.keyUpDown.unsubscribe();
  }
© www.soinside.com 2019 - 2024. All rights reserved.