Передайте другой элемент в ng-click - PullRequest
0 голосов
/ 21 ноября 2019

Я хочу создать список элементов, представляющих собой простой кликабельный текст. Каждый раз, когда вы нажимаете на элемент, он преобразуется во ввод (текстовое поле), и вы можете редактировать его. Я уже сделал это. Единственное, чего мне не хватает - это установить фокус на элементе ввода , когда я нажимаю на элемент. Мой HTML-код выглядит следующим образом:

<div ng-repeat="item in items">
  <span ng-if="!valueIsEditedForItem(item.id)">
    <a href="" ng-click="editValueForItem(item.id)">
      {{ item.value }}
    </a>
  </span>
  <span ng-if="valueIsEditedForItem(item.id)">
    <input ng-model="edited_value"
           ng-keyup="onValueInput($event, item.id, edited_value)"/>
  </span>
</div>

Элемент <a> и элемент <input> - это два разных элемента. Итак, моя идея состоит в том, чтобы как-то передать элемент ввода в ng-click="editValueForItem(item.id). Это должно выглядеть примерно так:

<a href="" ng-click="editValueForItem(item.id, inputElement)">
  {{ item.value }}
</a>

Тогда я смогу установить фокус на элемент ввода, выполнив это:

inputElement.focus();

Я знаю, что переменная $eventсодержит элемент события в $event.target. Но мое событие на <a>, а не на <input>. Как я могу ссылаться на элемент <input> в <a>?


РЕДАКТИРОВАТЬ: Решение

После прочтения предложений решения отответы, я наконец-то реализовал это, сославшись на идентификатор:

HTML

<input id="{{'input' + item.id}}"
       ng-model="edited_value"
       ng-keyup="onInput($event, item.id, edited_value)"/>

JS

$scope.editValueForItem = function (itemId) {
  $scope.currentlyEditedItemId = itemId;

  // focus on the input element
  setTimeout(function () {
    var inputElement = document.getElementById("input" + itemId);
    if (inputElement) {
      inputElement.focus();
    }
  }, 0);
};

Предложение setTimeout необходимо отдавать приоритет инициализации элемента. Если вы удалите его, то команда getElementById вернет ноль, поскольку элемент ввода еще не был инициализирован.

Однако решение с созданием моей собственной директивы было бы более подходящим вариантом.

1 Ответ

1 голос
/ 21 ноября 2019

Прямой подход заключается в добавлении некоторой ссылки, например:

<input ng-model="edited_value" editable="{{item.id}}"
       ng-keyup="onValueInput($event, item.id, edited_value)"/>
// editValueForItem method
$timeout(() => angular.element(document.querySelector('[editable="' + itemId + '"]')).focus())

Другой может быть:

<input ng-model="edited_value" take-focus-on-init
       ng-keyup="onValueInput($event, item.id, edited_value)"/>

, где take-focus-on-init - это директива, которая фокусирует элемент в функции ссылки.

Третий - сделать директиву:

<editable value="item.value"></editable>

с шаблоном:

<div ng-if="!inEditMode">{{item.value}}</div>
<div ng-if="inEditMode"><input ...</div>

здесь вы можете использовать простые element.find('input').focus()

...