javascript - 触发 AngularJS ng-model pipeline onBlur

标签 javascript angularjs validation directive angularjs-ng-model

我有这个$parser,它限制用户输入的字符数:

  var maxLength = attrs['limit'] ? parseInt(attrs['limit']) : 11;

  function fromUser(inputText) {
      if (inputText) {
          if (inputText.length > maxLength) {
              var limitedText = inputText.substr(0, maxLength);
              ngModel.$setViewValue(limitedText);
              ngModel.$render();
              return limitedText;
          }
      }
      return inputText;
  }

  ngModel.$parsers.push(fromUser);

我想在具有 ng-model-options="{updateOn: 'blur'}" 的输入元素上使用此指令,但存在一个问题,整个 $解析器 事物在用户失去输入元素的焦点后执行,我希望它在用户在输入字段中键入内容时执行。

(function (angular) {
    "use strict";
    angular.module('app', [])
    .controller("MainController", function($scope) {
      $scope.name = "Boom !";
      $scope.name2 = "asdf";
    }).directive('limitCharacters', limitCharactersDirective);

    function limitCharactersDirective() {
        return {
            restrict: "A",
            require: 'ngModel',
            link: linkFn
        };

        function linkFn(scope, elem, attrs, ngModel) {
            var maxLength = attrs['limit'] ? parseInt(attrs['limit']) : 11;

            function fromUser(inputText) {
                if(inputText) {
                    if (inputText.length > maxLength) {
                        var limitedText = inputText.substr(0, maxLength);
                        ngModel.$setViewValue(limitedText);
                        ngModel.$render();
                        return limitedText;
                    }
                }
                return inputText;
            }

            ngModel.$parsers.push(fromUser);
        }
    }

})(angular);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>

<div ng-app="app">
  without ng-model-options: <input type="text" ng-model="name" limit-characters limit="7" />
  
  <br>
  with ng-model-options <input type="text" ng-model="name2" ng-model-options="{updateOn: 'blur'}" limit-characters limit="7" />
</div>

最佳答案

当用户在输入中输入某些值时,$setViewValue 会在内部调用。如 angular docs 中所述这就是 $setViewValue 的作用:

When $setViewValue is called, the new value will be staged for committing through the $parsers and $validators pipelines. If there are no special ngModelOptions specified then the staged value is sent directly for processing through the $parsers pipeline. After this, the $validators and $asyncValidators are called and the value is applied to $modelValue. Finally, the value is set to the expression specified in the ng-model attribute and all the registered change listeners, in the $viewChangeListeners list are called.

In case the ngModelOptions directive is used with updateOn and the default trigger is not listed, all those actions will remain pending until one of the updateOn events is triggered on the DOM element.

这意味着 $parsers 仅用于实际模型更改提交(在您的情况下发生在模糊时)。

解决您的问题的最简单的方法是不使用 $parsers 来限制字符。检查此中的其他解决方案question .

使用获得最多支持的答案,您可以修改您的指令,使其看起来像这样:

function limitCharactersDirective() {
    return {
        restrict: "A",
        require: 'ngModel',
        link: linkFn
    };

    function linkFn(scope, elem, attrs, ngModel) {
        var maxLength = attrs['limit'] ? parseInt(attrs['limit']) : 11;
        angular.element(elem).on("keypress", function(e) {
            if (this.value.length == maxLength) e.preventDefault();
        });
    }
}

Check this JSFiddle一个工作示例。

关于javascript - 触发 AngularJS ng-model pipeline onBlur,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43949836/

相关文章:

javascript - 如何只选择顶部元素文本?

javascript - 动态修改javascript对象

asp.net-mvc - 使用 Angular VS Razor 进行 ASP.Net MVC 验证

validation - chalice : how to validate single field in command object

javascript - 如何在 Javascript 中使用 Perl 的时间戳?

javascript - 如何使用lodash过滤数据

angularjs - Meteor中的包冲突: Angular2 and Templating

javascript - AngularJS 停止阻塞形式

php-登录验证不起作用

java - 聚合异常