Возникла проблема с атрибутом autofocus в сотрудничестве с Angular. Подробно у меня есть <form> с <input type = "text"> наверху, который изначально определяется условием.
<input [attr.autofocus] = "selection===-1"
[(ngModel)] = "myForm.firstInpElem"
name = "firstInpElem"
placeholder = "firstInpElem">
Это работает, как ожидалось (Chrome).
Затем форма продолжается с выбором между двумя вариантами, управляемыми <input type = "radio">.
После того, как выбор сделан, отображается соответствующий элемент, а затем должен появиться autofocus.
Но этого не происходит, и я не понимаю причины этого.
Подготовлен stackblitz с рабочим примером, но в основном ниже находится разметка, которая не будет работать должным образом
<h1>Forms example</h1>
<form>
<pre>Condition to focus "firstInpElem" is {{selection===1|json}}</pre>
<p>This input element is autofocussed on page load</p>
<p>
<input [attr.autofocus] = "selection===-1"
[(ngModel)] = "myForm.firstInpElem"
name = "firstInpElem"
placeholder = "firstInpElem">
</p>
<p>
Provide one of both information:<br>
<label>
<input [(ngModel)] = "selection"
name = "radioInpElem"
type = "radio"
[value] = "1">
Option 1
</label>
<br>
<label>
<input [(ngModel)] = "selection"
name = "radioInpElem"
type = "radio"
[value] = "2">
Option 2
</label>
</p>
<pre>Condition to focus "secondInpElem" is {{selection===1|json}}</pre>
<pre>Condition to focus "thirdInpElem" is {{selection===2|json}}</pre>
<p>
<input *ngIf = "selection===1"
[attr.autofocus] = "selection===1"
[(ngModel)] = "myForm.secondInpElem"
name = "secondInpElem"
placeholder = "secondInpElem">
<input *ngIf = "selection===2"
[attr.autofocus] = "selection===2"
[(ngModel)] = "myForm.thirdInpElem"
name = "thirdInpElem"
placeholder = "thirdInpElem">
</p>
</form>
<pre>{{myForm|json}}</pre>






Если вы проверите инструменты разработки (инструменты F12), вы увидите, что новый элемент управления вводом фактически получает атрибут autofocus, но не получает фокус. Это потому, что autofocus устанавливает фокус на элемент когда страница загружается. В вашем случае страница уже загружена, когда новый элемент становится видимым.
Вместо этого вы можете программно установить фокус на новом элементе ввода. Для этого вы можете определить общую ссылочную переменную шаблона для двух входных элементов, имеющих условие ngIf:
<input #inputElement *ngIf = "selection === 1"
[(ngModel)] = "myForm.secondInpElem"
name = "secondInpElem"
placeholder = "secondInpElem">
<input #inputElement *ngIf = "selection === 2"
[(ngModel)] = "myForm.thirdInpElem"
name = "thirdInpElem"
placeholder = "thirdInpElem">
и отслеживайте наличие этих элементов с помощью ViewChildren и события QueryList.changes. Каждый раз, когда один из элементов ввода становится видимым, вы устанавливаете на нем фокус:
@ViewChildren("inputElement") inputElements: QueryList<ElementRef>;
ngAfterViewInit() {
this.inputElements.changes.subscribe(() => {
this.inputElements.last.nativeElement.focus();
});
}
См. этот stackblitz для демонстрации.
Другой вариант - скрыть входные данные (не использовать * ngIf else display.style) и ссылочные переменные. см. https://stackblitz.com/edit/angular-sbc4pp?file=src%2Fapp%2Fapp.component.html
<label>
<input [ngModel] = "selection" (change) = "change(second,1)"
name = "radioInpElem"
type = "radio"
[value] = "1">
Option 1
</label>
<br>
<label>
<input [ngModel] = "selection" (change) = "change(third,2)"
name = "radioInpElem"
type = "radio"
[value] = "2">
Option 2
</label>
<input #second [style.display] = "selection===1?'inherit':'none'"
[(ngModel)] = "myForm.secondInpElem"
name = "secondInpElem"
placeholder = "secondInpElem">
<input #third [style.display] = "selection===2?'inherit':'none'"
[(ngModel)] = "myForm.thirdInpElem"
name = "thirdInpElem"
placeholder = "thirdInpElem">
Ваша функция изменится, как
change(element:any,index:number)
{
this.selection=index;
setTimeout(()=>{element.focus()},0);
}
Спасибо @ConnorsFan, все работает отлично. Не знал, что автофокус применяется только при загрузке страницы