AngularJS директива для фокусировки в поле ввода: зачем нужен вызов setTimeout, чтобы он работал? - PullRequest
0 голосов
/ 12 февраля 2020

Я определил директиву angularjs, целью которой является автоматическое включение фокуса на элемент input HTML.

Код для директивы следующий:

function autoFocus() {
    return {
        restrict: 'A',
        scope: false,
        link: function ($scope, $element, $attrs) {
            $scope.$watch($attrs.autoFocus, function(newValue, oldValue) {
                if (!newValue) {
                    return;
                }

                const element = $element[0];
                setTimeout(function() {
                    element.focus();
                }, 0);
            });
        }
    };
}

angular
    .module('app')
    .directive('autoFocus', autoFocus);

Это пример использования:

<input 
      ng-show="isEditMode" 
      ng-model="item.title"
      ng-blur="todo.updateTodo(item, $index); isEditMode = false;"
      auto-focus="isEditMode">

Если я удаляю вызов setTimeout из код обратного вызова директива не работает должным образом (событие фокуса не вызывается, как я ожидал).

Может кто-нибудь объяснить мне, почему вызов setTimeout необходим для того, чтобы он работал?

1 Ответ

2 голосов
/ 12 февраля 2020

Это общая проблема директив, функция link запускается до того, как DOM завершил рендеринг, поэтому element еще не имеет значения. Самое простое (и, вероятно, самое чистое) решение - это использование $timeout, которое запускает новый цикл дайджеста и обеспечивает визуализацию DOM.

(Вы должны заменить setTimeout на angular s $timeout service)

...