javascript - 如何防止模型失效?

标签 javascript angularjs validation

我是最佳实践的坚定拥护者,尤其是在 Angular 方面,但我无法使用全新的 $validators 管道功能。

案例非常简单:1 个输入由使用 $parser$formatter 和一些 $validators 的指令增强:

<input name="number" type="text" ng-model="number" number> 

这是(简化的)指令:

myApp.directive('number', [function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    /*
     * Must have higher priority than ngModel directive to make
     * number (post)link function run after ngModel's one.
     * ngModel's priority is 1.
     */
    priority: 2,
    link: function($scope, $element, $attrs, $controller) {
      $controller.$parsers.push(function (value) {
        return isFinite(value)? parseInt(value): undefined;
      });

      $controller.$formatters.push(function (value) {
        return value.toString() || '';
      });

      $controller.$validators.minNumber = function(value) {
        return value && value >= 1;
      };

      $controller.$validators.maxNumber = function(value) {
        return value && value <= 10;
      };
    }
  };
}]);

I made a little plunk to play with :)

我试图实现的行为是:考虑到存储在作用域中的初始值是有效的,防止它在用户输入无效时被破坏。保留旧的直到设置新的有效的。

注意:在 Angular 1.3 之前,我可以直接在 $parser/$formatter 中使用 ngModelController API 来做到这一点。我仍然可以用 1.3 做到这一点,但那不是“Angular 方式”。

NB2:在我的应用程序中,我并没有真正使用数字,而是 quantities .问题依旧。

最佳答案

看起来您希望在验证后进行一些解析,将模型设置为最后一个有效值而不是从 View 派生的值。但是,我认为 1.3 管道以相反的方式工作:解析发生在验证之前。

所以我的回答是按照您在 1.2 中的做法进行操作:使用 $parsers 设置验证键并将用户的输入转换回最新的有效值。

以下指令执行此操作,并在指令中指定了一组按顺序运行的验证器。如果前面的任何验证器失败,则后面的验证器不会运行:它假定一次可能发生一个验证错误。

与您的问题最相关的是,它维护模型中的最后一个有效值,并且仅在未发生验证错误时才覆盖。

myApp.directive('number', [function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    /*
     * Must have higher priority than ngModel directive to make
     * number (post)link function run after ngModel's one.
     * ngModel's priority is 1.
     */
    priority: 2,
    link: function($scope, $element, $attrs, $controller) {
      var lastValid;

      $controller.$parsers.push(function(value) {
        value = parseInt(value);
        lastValid = $controller.$modelValue;

        var skip = false;
        validators.forEach(function(validator) {
          var isValid = skip || validator.validatorFn(value);
          $controller.$setValidity(validator.key, isValid);
          skip = skip || !isValid;
        });
        if ($controller.$valid) {
          lastValid = value;
        }
        return lastValid;
      });

      $controller.$formatters.push(function(value) {
        return value.toString() || '';
      });

      var validators = [{
        key: 'isNumber',
        validatorFn: function(value) {
          return isFinite(value);
        }
      }, {
        key: 'minNumber',
        validatorFn: function(value) {
          return value >= 1;
        }
      }, {
        key: 'maxNumber',
        validatorFn: function(value) {
          return value <= 10;
        }
      }];
    }
  };
}]);

这可以在 http://plnkr.co/edit/iUbUCfJYDesX6SNGsAcg?p=preview 上看到

关于javascript - 如何防止模型失效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26892845/

相关文章:

javascript - 如何向 mousemove 事件添加一些缓冲区,以便它不会中断 mouseup 事件

javascript - googlemaps 多边形与 clipper.js 的结合

django - 检查所有 {% url %} 标签是否有错误

javascript - 欧芹js : Form validation for password field(minlength) not working as expected

javascript - 如果我们从函数构造函数创建一个名为 'a' 的对象,那么为什么 'a' 不是 Function 的实例?

javascript - 如何将对数刻度应用于 Google Materials 条形图的轴

javascript - Angular 形式的日期选择器

javascript - Karma/jasmine Angular 指令提交点击单元测试在成组运行时失败,但不是单独运行

Angularjs:ReferenceError:未定义范围

javascript - 使用 JavaScript 处理 Html &lt;input pattern> - 超出时失败