Angular — фокусировка на вводе с динамическими идентификаторами при нажатии

#angular #input #focus #closest #elementref

#angular #ввод #фокусировка #ближайший #elementref

Вопрос:

* Есть много похожих вопросов, но я не нашел истинного дубликата, который отвечал бы на мой вопрос, извиняюсь, если я что-то пропустил.

У меня есть страница с несколькими входами / кнопками (повторяется один и тот же компонент), и мне нужно сосредоточиться на правильном вводе при нажатии кнопки.

Я пробовал варианты ElementRef, nativeElement, фокусировки на основе идентификатора… но я могу заставить его сосредоточиться только на первом в DOM или конкретных…

 <ng-template #myTemplate let-context="context">
<input #foo [id]="'myInput' context.id" />
<button class="btn" [id]="'btnAction' context.id (click)="focusOnInput()"></button>
</ng-template>
 

Который отображается так в DOM:

 <input #foo id="myInput1" />
<button class="btn" id="btnAction1></button>

<input #foo id="myInput2" />
<button class="btn" id="btnAction2></button>

<input #foo id="myInput3" />
<button class="btn" id="btnAction3></button>
 

Это то, что я пытался:

 @ViewChild("foo") focusOnThis: ElementRef;
focusOnInput(): void {
this.focusOnThis.nativeElement.focus();
}
 

Желаемое поведение:
При нажатии на кнопку фокусируйтесь на соответствующем вводе.
В настоящее время он фокусируется только на первом или на любом другом идентификаторе, который я укажу…

Ответ №1:

Вы можете вызвать foo.focus() обработчик нажатия кнопки. Поскольку область действия ссылочной переменной шаблона является #foo экземпляром шаблона, она будет ссылаться на элемент ввода родственного типа.

 <ng-template #myTemplate let-context="context">
  <input #foo />
  <button class="btn" (click)="foo.focus()"></button>
</ng-template>
 

Смотрите Этот stackblitz для демонстрации.


Если вам нужно установить фокус из метода, перейдите foo к нему в качестве аргумента:

 <ng-template #myTemplate let-context="context">
  <input #foo />
  <button class="btn" (click)="focusOnInput(foo)"></button>
</ng-template>
 
 focusOnInput(input): void {
  // Do something else here
  ...
  input.focus();
}
 

Комментарии:

1. ценю ответ. это кажется чистым и простым, но, к сожалению, это не работает в моем проекте. есть и другие события, которые должны запускаться первыми, чтобы сделать входные данные видимыми, так что я предполагаю, что это вызывает проблемы. Желательно, чтобы я установил фокус из функции в файле ts, чтобы я мог сначала запустить другие материалы….

2. Кстати, с шаблоном, указанным в вопросе, элемент ввода виден, когда видна кнопка. Если происходит что-то еще, из-за чего ввод не виден, пожалуйста, включите соответствующий код / разметку в вопрос или создайте stackblitz, чтобы показать проблему.

Ответ №2:

Как насчет использования атрибута данных с идентификатором и получения от него входных данных?

 <ng-template #myTemplate let-context="context">
<input [attr.data-group]="context.id" />
<button class="btn" [attr.data-group]="context.id" (click)="focusOnInput($event)"></button>
</ng-template>
 
 <input data-group="1" />
<button class="btn" data-group="1"></button>

<input data-group="2" />
<button class="btn" data-group="2"></button>

<input data-group="3" />
<button class="btn" data-group="3"></button>
 
 // component constructor
constructor(
    private readonly elementRef: ElementRef,
    // ...
  ) {
    // ...
  }

focusOnInput(event: MouseEvent): void {
    const groupId = (<HTMLElement>event.target).dataset.group;
    const input = this.elementRef.nativeElement.querySelector(`input[data-group="${groupId}"]`);
    input.focus();
}
 

Комментарии:

1. это умная идея — к сожалению, я получаю сообщение об ошибке, которое не может быть привязано к «group», поскольку оно не является известным свойством button… не уверен, почему…

2. Ах, извините. Не проверял это. Только что обновил шаблон. Это связано с тем, что обычная кнопка не обладает этим свойством. Но вы могли бы использовать attr. для указания angular, вы просто хотите установить атрибут html.