以编程方式将焦点更改为新的表单元素 - 复杂的用例

时间:2018-05-14 13:42:21

标签: angular user-experience angular-template

我正在构建Angular4应用程序。我只使用键盘在良好的用户体验和表单字段之间导航。我有这样的问题,当用户按下Tab键并到达此+标志(图1)时,按下Enter键,然后此按钮移动到下一行(图2) ,重点丢失了。问题是如何处理此Enter键以将焦点移至下一行并将焦点selector放在其上(默认情况下为Merchant URL值。)

现在,当用户在Enter上按+时,由于* ngIf并且生成了新行,模板中的此按钮会消失。任何建议如何使这个实现良好的键盘用户体验?如何将焦点从消失+更改为已经不可见的下一行组件,但在处理Enter时,它将会显示。

图1。 enter image description here

图2。 enter image description here

[溶液]

import { DOCUMENT } from '@angular/common';
import { Component, Inject, AfterViewChecked } from '@angular/core';

constructor(
    @Inject(DOCUMENT) private _document: Document
) { // bla bla bla }

由于我在模板中控制生成的元素id,我可以在处理id密钥期间存储我想要关注的元素的Enter,我需要实现AfterViewChecked

onEnter() {
    this.focusOn = 'my-generated-element-id';
    // put new model data to the array so template can generate new row
}

// this method is called very frequently so I only need to set focus
// when I need it and then clear focusOn variable.
ngAfterViewChecked(): void {
    if (this.focusOn) {
        let element = this._document.getElementById(this.focusOn);
        if (element) {
            element.focus();
            this.focusOn = null;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您可以使用ViewChildren跟踪input或其中的任何元素。然后订阅QueryList中的更改。在那里,您可以专注于最后添加的实例。

这是minimal example in stackblitz

import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit{
  name = 'Angular 6';
  items = ['Item1', 'item2'];
  @ViewChildren('input') inputs: QueryList<any>;

  ngAfterViewInit() {
    this.inputs.changes.subscribe(changes => {
      changes.last.nativeElement.focus();
    })
  }
  addItem() {
    this.items.push(`Item${this.items.length + 1}`)
  }
}
<hello name="{{ name }}"></hello>
<div *ngFor="let item of items">
  <input #input [placeholder]="item"/>
</div>
<button type="button" (click)="addItem()">Add Item</button>

这是您想要关注添加的新行中的输入。要关注+按钮,您可以使用ViewChild代替。如果那不是您想要的,请尝试在Stackblitz中创建一个最小的例子。