HTML5: How to set focus on a text input in a list with AngularJS

后端 未结 4 1450
闹比i
闹比i 2020-12-11 18:37

I use AngularJS with the ng-repeat directive to show an array of objects as a list.

  • 相关标签:
    4条回答
    • 2020-12-11 18:41

      Here is another directive implementation that uses 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();
          });
        }
      });
      

      Note that an interpolated DOM attribute value (i.e., {{cue.isNewest}}) always evaluates to a string, hence the reason newvalue is compared to the string 'true' rather than keyword true.

      HTML:

      <input type="text" ng-model="cues[$index].text" focus="{{cue.isNewest}}"
       class="input-xlarge" />{{cue.isNewest}}
      

      This fiddle also has a method to toggle which item in the array should have the focus.

      Note that if you do not load jQuery, we need to use element[0].focus() in the link function (not element.focus()) becaues jqLite doesn't have a focus() method.

      0 讨论(0)
    • 2020-12-11 18:41

      There is no special feature in AngularJS to receive focus. You could solve this with a $watch in your controller, but also with a directive.

      0 讨论(0)
    • 2020-12-11 18:55

      Since you would be manipulating the DOM, you will need to create a directive. Something like:

      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}}"/>
      

      Note: untested.

      0 讨论(0)
    • 2020-12-11 19:00

      The other proposed answers work OK 9/10 times for me, but soon I was running in "$digest already in progress" fun.

      I have a slightly modified version of the previous answers by asgoth and Mark Rajcok. Basically you inject the $timeout dependency and put the focus() call inside of a timeout(...). IIRC ng-focus does the same.

      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(); });
                      }
                  });
              }
          };
      }]);
      
      0 讨论(0)
    提交回复
    热议问题