AngularJS 聚焦输入字段的指令:为什么需要调用 setTimeout 才能使其工作?

AngularJS directive to focus in an input field: why is the call to setTimeout needed to make it work?

我定义了一个 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 才能使其正常工作?

这是一个常见的指令问题,link 函数在 DOM 完成渲染之前运行,因此 element 还没有值。最简单(也可能是最干净)的解决方案是使用 $timeout 触发新的摘要循环并确保 DOM 已呈现。

(您应该将 setTimeout 替换为 angular 的 $timeout 服务)