本文介绍了如何防止模型无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是最佳实践的坚定倡导者,尤其是在角度方面,但是我无法按原样使用全新的$validators管道功能.

I am a strong advocate of best practices, especially when it comes to angular but I can't manage to use the brand new $validators pipeline feature as it should be.

情况非常简单:1个输入通过使用$parser$formatter和某些$validators的指令进行了增强:

The case is quite simple: 1 input enhanced by a directive using $parser, $formatter and some $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来做到这一点,但那不是角度方式".

NB: Before angular 1.3, I was able to do this using ngModelController API directly in $parser/$formatter. I can still do that with 1.3, but that would not be "angular-way".

NB2:在我的应用中,我并不是真的在使用数字,而是数量.问题仍然存在一样.

NB2: In my app I am not really using numbers, but quantities.The problem remains the same.

推荐答案

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

It looks like you want some parsing to happen after validation, setting the model to the last valid value rather than one derived from the view. However, I think the 1.3 pipeline works the other way around: parsing happens before validation.

所以我的答案是像在1.2中一样进行操作:使用$parsers设置验证密钥并将用户的输入转换回最新的有效值.

So my answer is to just do it as you would do it in 1.2: using $parsers to set the validation keys and to transform the user's input back to the most recent valid value.

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

The following directive does this, with an array of validators specified within the directive that are run in order. If any of the previous validators fails, then the later ones don't run: it assumes one validation error can happen at a time.

与您的问题最相关的是,它保留了模型中的最后一个有效值,并且仅当没有发生验证错误时才覆盖.

Most relevant to your question, is that it maintains the last valid value in the model, and only overwrites if there are no validation errors occur.

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=预览

这篇关于如何防止模型无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 20:39