Обновить атрибут «автофокус» через взаимодействие на уровне шаблона в angular

Возникла проблема с атрибутом 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>
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
3
0
1 025
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если вы проверите инструменты разработки (инструменты 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 для демонстрации.

Спасибо @ConnorsFan, все работает отлично. Не знал, что автофокус применяется только при загрузке страницы

Bernhard 03.09.2018 22:25

Другой вариант - скрыть входные данные (не использовать * 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);
  }

Другие вопросы по теме