如何设置焦点在输入字段?

时间:2013-02-12 13:08:53

标签: angularjs angularjs-directive

在AngularJS中设置焦点于输入字段的'Angular方式'是什么?

更具体的要求:

  1. 当打开Modal时,请将焦点设置在此模态中的预定义<input>上。
  2. 每次<input>变得可见(例如,点击某个按钮),请将焦点设置在其上。
  3. 带有autofocus

    I tried to achieve the first requirement,但这仅适用于首次打开模态的情况,并且只在某些浏览器中有效(例如在Firefox中不起作用)。

    任何帮助将不胜感激。

34 个答案:

答案 0 :(得分:569)

  
      
  1. 打开模态时,将焦点设置在预定义的&lt; input&gt;上。在这个模态中。
  2.   

定义一个指令并让它$ 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));
            });
        }
    };
}]);

Plunker

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

  

'2'。每次&lt; input&gt;变得可见(例如通过点击某个按钮),将焦点设置在它上面。

创建一个与上面指令基本相似的指令。观察一些范围属性,当它变为真时(在你的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;
          //});
        }
      });
    }
  };
});

Plunker


2013年第3期更新:我见过一些人使用我原来的隔离范围指令,然后遇到嵌入式输入字段的问题(即模态中的输入字段)。没有新范围(或可能是新的子范围)的指令应该可以缓解一些痛苦。所以上面我更新了不使用隔离范围的答案。以下是原始答案:

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

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(); 
          });
        }
      });
    }
  };
});

Plunker

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

<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;
          //});
        }
      });
    }
  };
});

Plunker

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

答案 1 :(得分:260)

(编辑:我在此解释下添加了更新的解决方案)

Mark Rajcok是男人...他的答案是一个有效的答案,但 有缺陷(对不起Mark)......

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

所以我建议这个替代解决方案:

使用事件,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开发人员,我们非常努力将范围形状的钉子敲入事件形状孔中。

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


更新的解决方案

在@ ShimonRachlenko的评论之后,我已经改变了我的方法。现在我使用服务和指令处理“幕后”事件的组合:

除此之外,它与上面概述的主题相同。

Here is a quick demo 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);
    });
  }
});

答案 2 :(得分:236)

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

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

用法是

<input name="theInput" auto-focus>

我们使用超时来让dom渲染中的东西,即使它是零,它至少等待它 - 这种方式适用于模态,还有什么呢?

答案 3 :(得分:87)

HTML有一个属性autofocus

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

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

答案 4 :(得分:60)

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

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

答案 5 :(得分:52)

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

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

这虽然不是完成任务的纯粹角度方式,但语法遵循角度样式。 Jquery使用Angular(jQLite =&gt; JQuery Light)间接地扮演角色并直接访问DOM。

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

答案 6 :(得分:30)

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

Working Example: 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 />

Full AngularJS Directive Docs: https://docs.angularjs.org/api/ng/service/$compile

答案 7 :(得分: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/

答案 8 :(得分:17)

这是我最初的解决方案:

plunker

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或$。

答案 9 :(得分:10)

对于那些将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...

答案 10 :(得分: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
                        }
                    }
                });
            }
        }
    };
});

答案 11 :(得分: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
        };
    }
})();

答案 12 :(得分:7)

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

这是一个例子。

在html文件中:

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

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

document.getElementById("myInputId").focus();

答案 13 :(得分:6)

首先,正确的方法是roadmap for 1.1。同时,您可以编写指令来实现设置焦点。

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

因为对焦点,模糊和选择存在相同的controller-modifies-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/

答案 14 :(得分:4)

如果你只想要一个由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();
                });
            });
        }
    }
});

答案 15 :(得分: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 />

答案 16 :(得分: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);
  }
});

答案 17 :(得分: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处理时发生。

答案 18 :(得分:3)

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

添加以下一个衬垫指令可以使HTML&#39;自动对焦&#39;属性对Angular.js有效。

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

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

<input type="text" autofocus>

答案 19 :(得分:3)

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

<强> HTML

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

<强> JS

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

-

N.B。:根据上下文,您可能需要包含超时功能。

N.B.²:使用controllerAs时,这几乎是一样的。只需将name="myForm"替换为name="vm.myForm",将其替换为JS vm.myForm.myText.$$element.focus();

答案 20 :(得分:2)

我编辑Mark Rajcok的focusMe指令,以便在一个元素中进行多重聚焦。

HTML:

<input  focus-me="myInputFocus"  type="text">
AngularJs Controller中的

$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);
                }
            });
        }
    };
});

答案 21 :(得分: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 />

答案 22 :(得分:2)

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

Add another model

答案 23 :(得分:2)

如果你正在使用modalInstance并拥有你可以使用的对象&#34;那么&#34;打开模态后执行操作。如果您没有使用modalInstance,并且硬编码以打开模态,则可以使用该事件。 $ timeout不是一个好的解决方案。

你可以做(​​Bootstrap3):

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

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

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

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

我希望这有帮助! :)

答案 24 :(得分: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选择器而不是&#34;输入&#34;

答案 25 :(得分:1)

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

  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. 请致电此服务。

答案 26 :(得分:1)

很容易..试试这个

HTML

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

的javascript

document.getElementById("ddl00").focus();

答案 27 :(得分: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>

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

答案 28 :(得分: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}">

答案 29 :(得分: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页面渲染时发生。

答案 30 :(得分: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();
        });
    }]);

答案 31 :(得分:0)

只是扔些咖啡。

app.directive 'ngAltFocus', ->
    restrict: 'A'
    scope: ngAltFocus: '='
    link: (scope, el, attrs) ->
        scope.$watch 'ngAltFocus', (nv) -> el[0].focus() if nv

答案 32 :(得分:0)

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

标记是标准的HTML /角度指令,添加了用于选择的id /类

<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()来强制摘要周期

答案 33 :(得分:-1)

与框架无关的纯JavaScript解决方案:

给出这样的形式:

<form name="myform">
    <input name="search" type="text">
</form>

您可以使用以下方法设置焦点:

document.myform.search.focus();