770

在AngularJS中设置焦点输入字段的“角度方式”是什么?

更具体的要求:

  1. 打开模态框时,将焦点设置<input>在此模态框内的预定义上。
  2. 每次<input>变得可见(例如,通过单击某个按钮),将焦点放在它上面。

我试图用 来实现第一个要求autofocus但这仅在第一次打开 Modal 时有效,并且仅在某些浏览器中有效(例如,在 Firefox 中它不起作用)。

任何帮助将不胜感激。

4

33 回答 33

591
  1. 打开 Modal 时,将焦点设置在此 Modal 内预定义的 <input> 上。

定义一个指令并让它 $watch 一个属性/触发器,以便它知道何时聚焦元素:

Name: <input type="text" focus-me="shouldBeOpen">

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh's comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

普朗克

似乎需要 $timeout 来给模态时间渲染。

“2。” 每次 <input> 变得可见时(例如通过单击某个按钮),将焦点设置在它上面。

创建一个基本上像上面那样的指令。观察一些范围属性,当它变为真时(在你的 ng-click 处理程序中设置它),执行element[0].focus(). 根据您的用例,您可能需要也可能不需要 $timeout :

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.focusMe, function(value) {
        if(value === true) { 
          console.log('value=',value);
          //$timeout(function() {
            element[0].focus();
            scope[attrs.focusMe] = false;
          //});
        }
      });
    }
  };
});

普朗克


7/2013 更新:我看到一些人使用我原来的隔离范围指令,然后遇到嵌入式输入字段(即模式中的输入字段)的问题。没有新范围(或可能有新子范围)的指令应该可以减轻一些痛苦。所以上面我更新了不使用隔离范围的答案。以下是原答案:

1. 的原始答案,使用隔离范围:

Name: <input type="text" focus-me="{{shouldBeOpen}}">

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '@focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === "true") { 
          $timeout(function() {
            element[0].focus(); 
          });
        }
      });
    }
  };
});

笨蛋

2. 的原始答案,使用隔离范围:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

笨蛋

由于我们需要在指令中重置 trigger/focusInput 属性,因此 '=' 用于双向数据绑定。在第一个指令中,“@”就足够了。另请注意,当使用“@”时,我们将触发器值与“true”进行比较,因为@ 总是产生一个字符串。

于 2013-02-12T16:23:14.677 回答
268

##(编辑:我在这个解释下面添加了一个更新的解决方案)

Mark Rajcok 就是那个人......他的回答是一个有效的答案,但它一个缺陷(对不起,马克)......

...尝试使用布尔值关注输入,然后模糊输入,然后尝试使用它再次关注输入。除非您将布尔值重置为 false,然后 $digest,然后将其重置为 true,否则它将不起作用。即使您在表达式中使用字符串比较,您也将被迫将字符串更改为其他内容,$digest,然后再将其更改回来。(这已通过 blur 事件处理程序解决。)

所以我提出了这个替代解决方案:

使用事件,Angular 被遗忘的特性。

JavaScript 毕竟喜欢事件。事件本质上是松耦合的,甚至更好的是,您避免在 $digest 中添加另一个 $watch。

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e) {
          elem[0].focus();
      });
   };
});

所以现在你可以像这样使用它:

<input type="text" focus-on="newItemAdded" />

然后在您的应用程序中的任何位置...

$scope.addNewItem = function () {
    /* stuff here to add a new item... */

    $scope.$broadcast('newItemAdded');
};

这太棒了,因为你可以用这样的东西做各种各样的事情。一方面,您可以与已经存在的事件联系起来。另一方面,您可以通过让应用程序的不同部分发布应用程序的其他部分可以订阅的事件来开始做一些聪明的事情。

无论如何,这类事情对我来说是“事件驱动”的。我认为作为 Angular 开发人员,我们非常努力地将 $scope 形状的钉子钉入事件形状的孔中。

这是最好的解决方案吗?我不知道。这是一个解决方案。


更新的解决方案

在@ShimonRachlenko 在下面发表评论之后,我稍微改变了这样做的方法。现在我使用服务和指令的组合来处理“幕后”事件:

除此之外,它与上面概述的原理相同。

这是一个快速演示 Plunk

###用法

<input type="text" focus-on="focusMe"/>
app.controller('MyCtrl', function($scope, focus) {
    focus('focusMe');
});

###来源

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on('focusOn', function(e, name) {
        if(name === attr.focusOn) {
          elem[0].focus();
        }
      });
   };
});

app.factory('focus', function ($rootScope, $timeout) {
  return function(name) {
    $timeout(function (){
      $rootScope.$broadcast('focusOn', name);
    });
  }
});
于 2013-08-18T03:30:45.823 回答
244

当您真正需要的只是这个时,我发现其他一些答案过于复杂

app.directive('autoFocus', function($timeout) {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            $timeout(function(){
                _element[0].focus();
            }, 0);
        }
    };
});

用法是

<input name="theInput" auto-focus>

我们使用超时来让 dom 中的东西渲染,即使它是零,它至少会等待它 - 这样这在模态和其他东西中也有效

于 2014-01-01T02:25:22.713 回答
92

HTML 有一个属性autofocus

<input type="text" name="fname" autofocus>

http://www.w3schools.com/tags/att_input_autofocus.asp

于 2015-09-29T12:43:52.480 回答
63

您还可以使用 angular 内置的 jqlite 功能。

angular.element('.selector').trigger('focus');

于 2013-12-11T08:35:10.387 回答
56

这很好用,并且是一种集中输入控制的角度方式

angular.element('#elementId').focus()

这虽然不是完成任务的纯角度方式,但语法遵循角度风格。Jquery 使用 Angular (jQLite => JQuery Light) 间接和直接访问 DOM。

如果需要,这个代码可以很容易地放在一个简单的角度指令中,元素可以直接访问。

于 2014-08-11T07:10:43.753 回答
30

我不认为 $timeout 是将元素集中在创建上的好方法。这是一种使用内置角度功能的方法,从角度文档的模糊深度中挖掘出来。请注意“链接”属性如何拆分为“前”和“后”,用于前链接和后链接功能。

工作示例:http://plnkr.co/edit/Fj59GB

// this is the directive you add to any element you want to highlight after creation
Guest.directive('autoFocus', function() {
    return {
        link: {
            pre: function preLink(scope, element, attr) {
                console.debug('prelink called');
                // this fails since the element hasn't rendered
                //element[0].focus();
            },
            post: function postLink(scope, element, attr) {
                console.debug('postlink called');
                // this succeeds since the element has been rendered
                element[0].focus();
            }
        }
    }
});
<input value="hello" />
<!-- this input automatically gets focus on creation -->
<input value="world" auto-focus />

完整的 AngularJS 指令文档:https://docs.angularjs.org/api/ng/service/$compile

于 2014-05-28T19:07:48.753 回答
17

我写了一个双向绑定焦点指令,就像最近的模型一样。

您可以像这样使用焦点指令:

<input focus="someFocusVariable">

如果您在控制器的任何位置创建 someFocusVariable 范围变量true,则输入将获得焦点。如果你想“模糊”你的输入,那么 someFocusVariable 可以设置为 false。这就像 Mark Rajcok 的第一个答案,但具有双向绑定。

这是指令:

function Ctrl($scope) {
  $scope.model = "ahaha"
  $scope.someFocusVariable = true; // If you want to focus initially, set this to true. Else you don't need to define this at all.
}

angular.module('experiement', [])
  .directive('focus', function($timeout, $parse) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
          scope.$watch(attrs.focus, function(newValue, oldValue) {
              if (newValue) { element[0].focus(); }
          });
          element.bind("blur", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=false"); 
              }, 0);
          });
          element.bind("focus", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=true");
              }, 0);
          })
      }
    }
  });

用法:

<div ng-app="experiement">
  <div ng-controller="Ctrl">
    An Input: <input ng-model="model" focus="someFocusVariable">
    <hr>
        <div ng-click="someFocusVariable=true">Focus!</div>  
        <pre>someFocusVariable: {{ someFocusVariable }}</pre>
        <pre>content: {{ model }}</pre>
  </div>
</div>

这是小提琴:

http://fiddle.jshell.net/ubenzer/9FSL4/8/

于 2013-07-19T06:49:14.940 回答
17

这是我原来的解决方案:

笨蛋

var app = angular.module('plunker', []);
app.directive('autoFocus', function($timeout) {
    return {
        link: function (scope, element, attrs) {
            attrs.$observe("autoFocus", function(newValue){
                if (newValue === "true")
                    $timeout(function(){element[0].focus()});
            });
        }
    };
});

和 HTML:

<button ng-click="isVisible = !isVisible">Toggle input</button>
<input ng-show="isVisible" auto-focus="{{ isVisible }}" value="auto-focus on" />

它能做什么:

当输入通过 ng-show 变得可见时,它会聚焦输入。这里没有使用 $watch 或 $on。

于 2014-06-11T20:58:50.740 回答
11

对于那些使用 Angular 和 Bootstrap 插件的人:

http://angular-ui.github.io/bootstrap/#/modal

您可以挂钩opened模态实例的承诺:

modalInstance.opened.then(function() {
        $timeout(function() {
            angular.element('#title_input').trigger('focus');
        });
    });

modalInstance.result.then(function ( etc...
于 2015-03-03T15:32:25.840 回答
8

我发现使用通用表达式很有用。这样你就可以在输入文本有效时自动移动焦点

<button type="button" moo-focus-expression="form.phone.$valid">

或者当用户完成一个固定长度的字段时自动聚焦

<button type="submit" moo-focus-expression="smsconfirm.length == 6">

当然在加载后关注

<input type="text" moo-focus-expression="true">

该指令的代码:

.directive('mooFocusExpression', function ($timeout) {
    return {
        restrict: 'A',
        link: {
            post: function postLink(scope, element, attrs) {
                scope.$watch(attrs.mooFocusExpression, function (value) {

                    if (attrs.mooFocusExpression) {
                        if (scope.$eval(attrs.mooFocusExpression)) {
                            $timeout(function () {
                                element[0].focus();
                            }, 100); //need some delay to work with ng-disabled
                        }
                    }
                });
            }
        }
    };
});
于 2015-04-30T09:15:27.673 回答
7

不要复活僵尸或插入我自己的指令(好吧,这正是我正在做的):

https://github.com/hiebj/ng-focus-if

http://plnkr.co/edit/MJS3zRk079Mu72o5A9l6?p=preview

<input focus-if />

(function() {
    'use strict';
    angular
        .module('focus-if', [])
        .directive('focusIf', focusIf);

    function focusIf($timeout) {
        function link($scope, $element, $attrs) {
            var dom = $element[0];
            if ($attrs.focusIf) {
                $scope.$watch($attrs.focusIf, focus);
            } else {
                focus(true);
            }
            function focus(condition) {
                if (condition) {
                    $timeout(function() {
                        dom.focus();
                    }, $scope.$eval($attrs.focusDelay) || 0);
                }
            }
        }
        return {
            restrict: 'A',
            link: link
        };
    }
})();
于 2015-02-23T00:12:38.970 回答
6

首先,官方关注的方式是1.1 的路线图。同时,您可以编写指令来实现设置焦点。

其次,在项目变得可见后将焦点设置在项目上,目前需要一种解决方法。只需使用 . 延迟对元素 focus() 的调用$timeout

因为焦点,模糊和选择存在相同的控制器修改DOM问题,我建议有一个ng-target指令:

<input type="text" x-ng-model="form.color" x-ng-target="form.colorTarget">
<button class="btn" x-ng-click="form.colorTarget.focus()">do focus</button>

角线程在这里:http: //goo.gl/ipsx4,更多详细信息在这里博客:http: //goo.gl/4rdZa

以下指令将.focus()在您的控制器内创建一个由您的ng-target属性指定的函数。(它也创建了一个.blur()和一个.select()。)演示:http: //jsfiddle.net/bseib/WUcQX/

于 2013-02-13T07:26:48.107 回答
6

可以简单地使用 javascript 函数来完成焦点,而不是创建自己的指令。

这是一个例子。

在 html 文件中:

<input type="text" id="myInputId" />

在文件 javascript 中,例如在控制器中,您想要激活焦点:

document.getElementById("myInputId").focus();
于 2014-06-20T14:56:35.807 回答
5

如果您只想要一个由 ng-click 控制的简单焦点。

html:

<input ut-focus="focusTigger">

<button ng-click="focusTrigger=!focusTrigger" ng-init="focusTrigger=false"></button>

指示:

'use strict'

angular.module('focus',['ng'])
.directive('utFocus',function($timeout){
    return {
        link:function(scope,elem,attr){
            var focusTarget = attr['utFocus'];
            scope.$watch(focusTarget,function(value){
                $timeout(function(){
                    elem[0].focus();
                });
            });
        }
    }
});
于 2014-02-17T18:06:26.853 回答
4

一个适用于模态的简单方法:

.directive('focusMeNow', ['$timeout', function ($timeout)
{
    return {
        restrict: 'A',

        link: function (scope, element, attrs)
        {


            $timeout(function ()
            {
                element[0].focus();
            });



        }
    };
}])

例子

<input ng-model="your.value" focus-me-now />
于 2016-01-13T15:35:47.657 回答
3

您可以只创建一个指令,强制关注 postLinking 上的装饰元素:

angular.module('directives')
.directive('autoFocus', function() {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            _element[0].focus();
        }
    };
});

然后在你的html中:

<input type="text" name="first" auto-focus/> <!-- this will get the focus -->
<input type="text" name="second"/>

这适用于模态和 ng-if 切换元素,不适用于 ng-show,因为 postLinking 仅发生在 HTML 处理上。

于 2013-12-26T16:25:20.510 回答
3

Mark 和 Blesh 有很好的答案;然而,Mark 有一个 Blesh 指出的缺陷(除了实现起来很复杂),我觉得 Blesh 的答案在创建一个专门关于向前端发送焦点请求的服务时存在语义错误,而他真正需要的只是一种方法延迟事件,直到所有指令都在监听。

所以这就是我最终做的事情,它从 Blesh 的回答中窃取了很多内容,但将控制器事件的​​语义和“加载后”服务分开。

这允许控制器事件很容易地被挂钩,而不是仅仅关注特定元素,并且还允许仅在需要时才产生“加载后”功能的开销,在许多情况下可能不会。

用法

<input type="text" focus-on="controllerEvent"/>
app.controller('MyCtrl', function($scope, afterLoad) {
  function notifyControllerEvent() {
      $scope.$broadcast('controllerEvent');
  }

  afterLoad(notifyControllerEvent);
});

来源

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e, name) {
        elem[0].focus();
      });
   };
});

app.factory('afterLoad', function ($rootScope, $timeout) {
  return function(func) {
    $timeout(func);
  }
});
于 2014-02-18T23:14:30.600 回答
3

这也是可以使用的ngModelController。使用 1.6+(不知道旧版本)。

HTML

<form name="myForm">
    <input type="text" name="myText" ng-model="myText">
</form>

JS

$scope.myForm.myText.$$element.focus();

--

注意:根据上下文,您可能必须包含一个超时函数。

NB²:使用 时controllerAs,几乎相同。只需在 JSname="myForm"中用and 替换, .name="vm.myForm"vm.myForm.myText.$$element.focus();

于 2017-02-21T13:59:46.333 回答
3

可能是 ES6 时代最简单的解决方案。

添加以下一个 liner 指令使 HTML 'autofocus' 属性在 Angular.js 上有效。

.directive('autofocus', ($timeout) => ({link: (_, e) => $timeout(() => e[0].focus())}))

现在,您可以使用 HTML5 自动对焦语法,例如:

<input type="text" autofocus>
于 2017-06-15T07:58:19.100 回答
2

这里只是一个新手,但我能够使用以下指令使其在ui.bootstrap.modal中工作:

directives.directive('focus', function($timeout) {
    return {
        link : function(scope, element) {
            scope.$watch('idToFocus', function(value) {
                if (value === element[0].id) {
                    $timeout(function() {
                        element[0].focus();
                    });
                }
            });
        }
    };
});

在 $modal.open 方法中,我使用以下内容来指示应将焦点放在哪里的元素:

var d = $modal.open({
        controller : function($scope, $modalInstance) {
            ...
            $scope.idToFocus = "cancelaAteste";
    }
        ...
    });

在模板上我有这个:

<input id="myInputId" focus />
于 2014-02-14T12:57:05.077 回答
2

我编辑 Mark Rajcok 的 focusMe 指令以在一个元素中实现多个焦点。

HTML:

<input  focus-me="myInputFocus"  type="text">

在 AngularJs 控制器中:

$scope.myInputFocus= true;

AngulaJS 指令:

app.directive('focusMe', function ($timeout, $parse) {
    return {
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                if (value === true) {
                    $timeout(function () {
                        scope.$apply(model.assign(scope, false));
                        element[0].focus();
                    }, 30);
                }
            });
        }
    };
});
于 2014-07-21T11:53:15.963 回答
2

以下指令对我有用。使用相同的 autofocus html 属性进行输入。

.directive('autofocus', [function () {
    return {
        require : 'ngModel',
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.focus();
        }
    };
}])
于 2015-08-06T03:41:17.050 回答
2

如果您正在使用 modalInstance 并拥有对象,则可以在打开模式后使用“then”执行操作。如果你没有使用modalInstance,并且硬编码打开modal,你可以使用事件。$timeout 不是一个好的解决方案。

你可以这样做(Bootstrap3):

$("#" + modalId).on("shown.bs.modal", function() {
    angular.element("[name='name']").focus();
});

在 modalInstance 中,您可以查看库以了解打开模式后如何执行代码。

不要像这样使用 $timeout,$timeout 可以是 0、1、10、30、50、200 或更多,这取决于客户端计算机,以及打开 modal 的过程。

不要使用 $timeout 让方法告诉你什么时候可以集中注意力;)

我希望这有帮助!:)

于 2015-09-21T14:35:14.130 回答
2

如果将所需的焦点元素注入指令模板中,则所有先前的答案都不起作用。以下指令适用于简单元素或指令注入元素(我在typescript中编写)。它接受内部可聚焦元素的选择器。如果您只需要关注 self 元素 - 不要将任何选择器参数发送到指令:

module APP.Directives {

export class FocusOnLoadDirective implements ng.IDirective {
    priority = 0;
    restrict = 'A';

    constructor(private $interval:any, private $timeout:any) {

    }

    link = (scope:ng.IScope, element:JQuery, attrs:any) => {
        var _self = this;
        var intervalId:number = 0;


        var clearInterval = function () {
            if (intervalId != 0) {
                _self.$interval.cancel(intervalId);
                intervalId = 0;
            }
        };

        _self.$timeout(function(){

                intervalId = _self.$interval(function () {
                    let focusableElement = null;
                    if (attrs.focusOnLoad != '') {
                        focusableElement = element.find(attrs.focusOnLoad);
                    }
                    else {
                        focusableElement = element;
                    }
                    console.debug('focusOnLoad directive: trying to focus');
                    focusableElement.focus();
                    if (document.activeElement === focusableElement[0]) {
                        clearInterval();
                    }
                }, 100);

                scope.$on('$destroy', function () {
                    // Make sure that the interval is destroyed too
                    clearInterval();
                });

        });
    };

    public static factory = ():ng.IDirectiveFactory => {
        let directive = ($interval:any, $timeout:any) => new FocusOnLoadDirective($interval, $timeout);
        directive.$inject = ['$interval', '$timeout'];
        return directive;
    };
}

angular.module('common').directive('focusOnLoad', FocusOnLoadDirective.factory());

}

简单元素的用法示例:

<button tabindex="0" focus-on-load />

内部元素的使用示例(通常用于动态注入元素,例如带有模板的指令):

<my-directive focus-on-load="input" />

您可以使用任何 jQuery 选择器而不是“输入”

于 2016-03-09T09:26:08.590 回答
2

如果您希望将重点放在特定元素上,可以使用以下方法。

  1. 创建一个名为focus.

    angular.module('application')
    .factory('focus', function ($timeout, $window) {
        return function (id) {
            $timeout(function () {
                var element = $window.document.getElementById(id);
                if (element)
                    element.focus();
            });
        };
    });
    
  2. 将其注入您希望调用的控制器中。

  3. 调用此服务。

于 2018-02-13T11:52:08.353 回答
1

在寻找更好的解决方案但没有找到它,不得不创建它之后,我想为这个讨论做出贡献。

标准: 1. 解决方案应该独立于父控制器范围以增加可重用性。2. 避免使用 $watch 来监视某些条件,这既慢又增加了摘要循环的大小并使测试更加困难。3. 避免使用 $timeout 或 $scope.$apply() 来触发摘要循环。4. 输入元素存在于使用指令的元素中打开。

这是我最喜欢的解决方案:

指示:

.directive('focusInput', [ function () {
    return {
        scope: {},
        restrict: 'A',
        compile: function(elem, attr) {
            elem.bind('click', function() {
                elem.find('input').focus();                
            });
        }        
    };
}]);

html:

 <div focus-input>
     <input/>
 </div>

我希望这会帮助那里的人!

于 2015-02-18T13:10:00.713 回答
1

这很容易..试试这个

html

<select id="ddl00">  
 <option>"test 01"</option>  
</select>

javascript

document.getElementById("ddl00").focus();
于 2017-07-28T08:20:08.877 回答
0

我认为该指令是不必要的。使用 HTML id 和 class 属性来选择所需的元素,并让服务使用 document.getElementById 或 document.querySelector 来应用焦点(或 jQuery 等效项)。

标记是标准的 HTML/angular 指令,添加了 id/classes 以供选择

<input id="myInput" type="text" ng-model="myInputModel" />

控制器广播事件

$scope.$emit('ui:focus', '#myInput');

在 UI 服务中使用 querySelector - 如果有多个匹配项(比如由于类),它将只返回第一个

$rootScope.$on('ui:focus', function($event, selector){
  var elem = document.querySelector(selector);
  if (elem) {
    elem.focus();
  }
});

您可能希望使用 $timeout() 强制执行摘要循环

于 2014-03-30T23:37:48.897 回答
0

只是扔了一些咖啡。

app.directive 'ngAltFocus', ->
    restrict: 'A'
    scope: ngAltFocus: '='
    link: (scope, el, attrs) ->
        scope.$watch 'ngAltFocus', (nv) -> el[0].focus() if nv
于 2014-06-10T22:16:38.027 回答
0

不确定依赖超时是否是一个好主意,但这适用于 ng-repeat,因为此代码在 angularjs 更新 DOM 之后运行,因此您确保所有对象都在那里:

myApp.directive('onLastRepeat', [function () {
        return function (scope, element, attrs) {
            if (scope.$last) setTimeout(function () {
                scope.$emit('onRepeatLast', element, attrs);
            }, 1);
        };
    }]);
    //controller for grid
    myApp.controller('SimpleController', ['$scope', '$timeout', '$http', function ($scope, $timeout, $http)
    {
        var newItemRemoved = false;
        var requiredAlert = false;
        //this event fires up when angular updates the dom for the last item
        //it's observed, so here, we stop the progress bar
        $scope.$on('onRepeatLast', function (scope, element, attrs) {
            //$scope.complete();
            console.log('done done!');
            $("#txtFirstName").focus();
        });
    }]);
于 2015-02-06T20:40:40.107 回答
0

您可以使用以下指令在 html 输入中获取 bool 值以专注于它...

//js file
angular.module("appName").directive("ngFocus", function () {
       return function (scope, elem, attrs, ctrl) {
             if (attrs.ngFocus === "true") {
                 $(elem).focus();
             }
             if (!ctrl) {
                 return;
             }
       elem.on("focus", function () {
            elem.addClass("has-focus");
            scope.$apply(function () {
                ctrl.hasFocus = true;
            });
        });
    };
});

<!-- html file -->
<input type="text" ng-focus="boolValue" />

您甚至可以在控制器中将函数设置为 ngFocus 指令值,注意下面的代码...

<!-- html file -->
<input type="text" ng-focus="myFunc()" />


//controller file
$scope.myFunc=function(){
      if(condition){
          return true;
      }else{
          return false;
      }
}

该指令在 html 页面呈现时发生。

于 2016-12-29T13:10:42.887 回答
0

以编程方式调用元素上的任何操作:click()、focus()、select()...

用法:

<a href="google.com" auto-action="{'click': $scope.autoclick, 'focus': $scope.autofocus}">Link</a>

指示:

/**
 * Programatically Triggers given function on the element
 * Syntax: the same as for ng-class="object"
 * Example: <a href="google.com" auto-action="{'click': autoclick_boolean, 'focus': autofocus_boolean}">Link</a>
 */
app.directive('focusMe', function ($timeout) {
    return {
        restrict: 'A',
        scope: {
            autoAction: '<',
        },
        link: function (scope, element, attr) {
            const _el = element[0];
            for (const func in scope.autoAction) {
                if (!scope.autoAction.hasOwnProperty(func)) {
                    continue;
                }
                scope.$watch(`autoAction['${func}']`, (newVal, oldVal) => {
                    if (newVal !== oldVal) {
                        $timeout(() => {
                            _el[func]();
                        });
                    }
                });
            }

        }
    }
});

要解决这个问题,请在控制器中(最好)在初始化时设置变量或设置为 ng-init:

 <input ng-init="autofocus=true" auto-action="{'focus': autofocus}">
于 2018-10-19T12:43:55.803 回答