Смена фокуса на новый элемент формы программно - сложный вариант использования - PullRequest
0 голосов
/ 14 мая 2018

Я создаю приложение 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 голосов
/ 14 мая 2018

Вы можете использовать ViewChildren для отслеживания input или любого другого элемента.Тогда подпишитесь на изменения в QueryList.Здесь вы можете сосредоточиться на последнем добавленном экземпляре.

Вот минимальный пример в 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.

...