【问题标题】:Enter key press behaves like a Tab in AngularEnter 按键的行为类似于 Angular 中的 Tab
【发布时间】:2019-08-30 21:49:19
【问题描述】:

我有一个 Angular 2+ 表单组,每个表单字段都有 tabIndex。

如何在每次按下 Enter 键时将焦点切换到下一个表单字段(类似于按 Tab)?

JavaScript 参考 - Enter key press behaves like a Tab in Javascript

【问题讨论】:

  • 我知道我的回答没有引起注意 :(,但是 stackoverflow.com/questions/53690973/…
  • @Eliseo,我已经尝试了代码,但在我动态生成控件的情况下不起作用。
  • 如果你把#nextTab 我不知道,因为不能工作。在函数 createKeydownEnter 中检查 -writing console.log(querycontrols.length) 以检查指令是否考虑了您的控制
  • 我尝试调试,querycontrols.length 总是为 0。即使我尝试使用 AfterViewChecked。
  • 查看新的stackblitz.com/edit/…。看看我如何引用 FormArray 中的控件,例如 [formControl]="lineas.at(i).get('prop1')" 我尝试使用 FormArrayName、GroupName 等但不起作用,但使用 formControl 就可以了。如果不起作用,请提供有关如何动态生成控件的更多数据

标签: angular enter tabindex


【解决方案1】:

我会用一个简单的指令和一个更简单的服务来做到这一点。

tab.directive.ts

import { Directive, Input, ElementRef, HostListener, OnInit } from '@angular/core';
import { TabService } from './tab.service';
type IKNOWISNUMBER = any;
type IKNOWISSTRING = any;

@Directive({
  selector: '[tabIndex]'
})
export class TabDirective implements OnInit {

  private _index: number;
  get index(): IKNOWISNUMBER{
    return this._index;
  }
  @Input('tabIndex')
  set index(i: IKNOWISSTRING){
    this._index = parseInt(i);
  }

  @HostListener('keydown', ['$event'])
  onInput(e: any) {
    if (e.which === 13) {
      this.tabService.selectedInput.next(this.index + 1)
      e.preventDefault();
    }
  }
  constructor(private el: ElementRef, private tabService: TabService) { 
  }

  ngOnInit(){
    this.tabService.selectedInput.subscribe((i) => {
      if (i === this.index){
        this.el.nativeElement.focus();
      }
    });
  }
}

tab.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
 
@Injectable()
export class TabService {
  selectedInput: BehaviorSubject<number> = new BehaviorSubject<number>(1);
}

我创建了一个小stackblitz 来展示它是如何工作的。

附: 请记住在每个组件中为 tab.service 提供一个表单,因为您需要为每个表单提供一个特定的实例。

【讨论】:

  • 如果你想看看我在顶部的评论
  • @Eliseo 我真的很喜欢它,但我有一个问题。 ViewChildren 已经通过 tabIndex 对控件进行排序,或者您必须在创建指令时以编程方式对其进行排序?
  • ViewChildren 按 DOOM 中的位置排列元素(我几乎相信这一点)。如果要更改,可以:首先使用 toArray 传递给数组,对数组进行排序,然后对已排序的数组使用 reset。
【解决方案2】:

这是一个非常简单的方法,只需几行代码(我也在此处发布:Change behavior of Enter key . . . ):

首先,当您动态创建Input 元素时,在Template 中:1. 使用唯一编号填充tabIndex 属性,2. 使用相同的唯一编号填充超级简单的自定义“标签”指令作为tabIndex,以及 3. 设置 Keydown "Enter" 事件监听器:

Template:

<ng-container *ngFor="let row in data">
   <input tabindex ="{{row[tabCol]}}" [appTag]="{{row[tabCol]}}" (keydown.enter)="onEnter($event)" . . . />
</ng-container>

在您的component,您的超级简单事件监听器onEnter():

@ViewChildren(TagDirective) ipt!: QueryList<ElementRef>;

  onEnter(e: Event) {
    this.ipt["_results"][(<HTMLInputElement>e.target).tabIndex%(+this.ipt["_results"].length-1)+1].el.nativeElement.focus();
  }

注意:模数 (%) 操作只是为了确保如果您在最后一个 Input,您将循环回到第一个输入。

超级简单、极简的“标签”Directive

import { Directive, ElementRef, Input } from '@angular/core';

@Directive({
  selector: '[appTag]'
})
export class TagDirective {
  @Input('appTag') id: number;

  constructor(public el: ElementRef) { }

}

甚至可能有一种方法可以完全摆脱“标签”`指令并使其更加简单,但我还没有时间弄清楚如何做到这一点。 . .

【讨论】:

    【解决方案3】:

    export class InputNumberComponent implements OnInit {
        @Input() model: number;
        @Input() tabIndex: number ;
        @Output()
        changedValue = new EventEmitter<number>();
        constructor() { }
        
        valueChanged(value): void {
            this.changedValue.emit(value);
        }
    }
      
      <input tabindex="{{tabIndex}}"  [(ngModel)]="model"  (change)="valueChanged(model)"/>
      

    如果使用 Angular 并让输入组件只在 html 中使用 html "tabindex"

    并定义@input 到.ts 文件获取tabindex @Input() tabIndex: number ;

    【讨论】:

      猜你喜欢
      • 2010-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-27
      • 1970-01-01
      • 2022-08-17
      • 2011-06-05
      相关资源
      最近更新 更多