HTML5:如何使用AngularJS设置列表中文本输入的焦点

HTML5:如何使用AngularJS设置列表中文本输入的焦点,html,input,focus,angularjs,Html,Input,Focus,Angularjs,我使用AngularJS和ng repeat指令将对象数组显示为列表 <li ng-repeat="cue in cues" class="form-inline"> <input type="text" ng-model="cues[$index].text" class="input-xlarge"/> {{cue.isNewest}} </li> {{cue.isNewest} 属性“islatest”仅在数组的一个元素上为tru

我使用AngularJS和ng repeat指令将对象数组显示为列表

<li ng-repeat="cue in cues" class="form-inline">
    <input type="text" ng-model="cues[$index].text" class="input-xlarge"/>
    {{cue.isNewest}}
</li>
  • {{cue.isNewest}

  • 属性“islatest”仅在数组的一个元素上为true。我想将键盘焦点设置为该项的文本输入。如何使用AngularJS实现这一点?

    AngularJS中没有接收焦点的特殊功能。您可以使用控制器中的$watch解决这个问题,但也可以使用一个指令。

    因为您要操作DOM,所以需要创建一个指令。比如:

    var app = angular.module('quirli', []);
    app.directive('focusable', function() {
        return {
            restrict: 'A',
            scope: {
                focusable: '@'
            },
            link: function(scope, elm, attrs) {
                scope.$watch('focusable', function (value) {
                    if (value) {
                        elm[0].focus();
                    }
                });
            }
        };
    });
    
    Html:

    <html ng-app="quirli" lang="en">
    ....  
    <input type="text" ng-model="cues[$index].text" class="input-xlarge" focusable="{{cue.isNewest}}"/>
    
    
    ....  
    

    注意:未测试。

    这里是另一个使用attrs的指令实现。$observe:

    myApp.directive('focus', function () {
      return function (scope, element, attrs) {
        attrs.$observe('focus', function (newValue) {
          newValue === 'true' && element[0].focus();
          // or, if you don't like side effects (see @Christophe's comment):
          //if(newValue === 'true')  element[0].focus();
        });
      }
    });
    
    请注意,插入的DOM属性值(即,
    {{cue.isNewest}}
    )总是计算为字符串,因此原因
    newvalue
    与字符串
    'true'
    进行比较,而不是关键字
    true

    HTML:

    {{cue.islatest}
    
    这也有一个方法来切换数组中哪个项应该具有焦点


    请注意,如果不加载jQuery,我们需要在链接函数中使用
    元素[0]。focus()
    (而不是
    元素。focus()
    ),因为jqLite没有focus()方法。

    其他建议的答案对我来说可以工作9/10次,但很快我就在“$digest ready in progress”中运行了

    我对asgoth和Mark Rajcok之前的答案做了一点修改。基本上,注入$timeout依赖项并将focus()调用放在超时(…)内。IIRC ng focus也做了同样的事情

    var app = angular.module('cgeers', []);
    app.directive('focus', ["$timeout", function ($timeout) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                scope.$watch(attrs.focus, function (value) {
                    if (value) {
                        $timeout(function() { element[0].focus(); });
                    }
                });
            }
        };
    }]);
    

    从这里开始,我研究了$watch:然而,我得出的结论是,我只能观察模型的变化。但是我的控制器不能操纵DOM,这也不是一个好的设计,好吧,控制器可以操纵DOM,但这不是一个好的设计。这是给你的一个指令:)Tanks asgoth用于这段代码。我稍微修改了它,添加了一个应用程序名,如图所示:聚焦功能现在起作用了,问题是文本框中的文本被省略了。我必须找出原因。我现在正在阅读上述指令文件。让我心烦意乱!如果未加载jQuery,请使用elm[0].focus()(即使加载了jQuery,也最好使用此语法,因为它应该始终有效)。正常工作……除非还使用ng focus/ng blur。然后你会遇到“$digest ready in progress”(已在进行中的$digest)”。被asgoth的答案所接受,因为它在第一次尝试时就起了作用,并且得到了很好的解释。
    预期会有一个赋值或函数调用,但却看到了一个表达式
    :我必须说,我已经多年没有在表达式中看到副作用了,除了在一些单行比赛中,它应该是'if(cond){focus here}'。
    var app = angular.module('cgeers', []);
    app.directive('focus', ["$timeout", function ($timeout) {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                scope.$watch(attrs.focus, function (value) {
                    if (value) {
                        $timeout(function() { element[0].focus(); });
                    }
                });
            }
        };
    }]);