10

我有一个称为验证指令valid-number,用于使用 $setValidity 设置表单的有效性 - 这对于我在输入框中键入的任何文本值都适用,该指令作为属性应用。

HTML是

<form name="numberForm">
<input name="amount" type="text" ng-model="amount" required  valid-number /></form>

指令如下

angular.module('test',[]).directive('validNumber',function(){
            return{
                require: "ngModel",
                link: function(scope, elm, attrs, ctrl){

                    var regex=/\d/;
                    ctrl.$parsers.unshift(function(viewValue){
                        var floatValue = parseFloat(viewValue);

                        if(regex.test(viewValue)){
                            ctrl.$setValidity('validNumber',true);
                        }
                        else{
                            ctrl.$setValidity('validNumber',false);
                        }
                        return viewValue;
                    });
                }
            };
        });

但是,如果第一次加载页面时输入框初始化的值无效,我也希望触发验证并将 css 设置为无效的 clsss,例如,如果我设置$scope.amount = 'not a number'了我希望输入框有该指令适用于它,但没有喜悦。为了not a number突出显示为无效,我必须更改输入的内容,这会触发指令。

如何确保该指令适用于<input> 初始化的任何内容?

完整的代码示例在这里;

http://jsfiddle.net/JW43C/5/

4

3 回答 3

16

$parsers数组包含一个函数列表,这些函数将应用于模型从视图中接收的值(用户输入的内容),$formatters数组包含在模型值显示在视图中之前应用于模型值的函数列表。

在您的指令中,您正确使用了数组,但如果您希望验证初始值,$parsers还需要添加数组:$formatters

angular.module('test',[]).directive('validNumber',function(){
  return{
    require: "ngModel",
    link: function(scope, elm, attrs, ctrl){
      var regex = /^\d$/;
      var validator = function(value){
        ctrl.$setValidity('validNumber', regex.test(value));
        return value;
      };

      ctrl.$parsers.unshift(validator);
      ctrl.$formatters.unshift(validator);
    }
  };
});

演示插件

于 2013-06-09T17:54:38.503 回答
1

您可以在链接阶段简单地调用您的验证函数,就像在这个小提琴中一样:

link: function(scope, elm, attrs, ctrl) {                       
    var regex=/\d/;
    var verificationFunction = function(viewValue) {
        var floatValue = parseFloat(viewValue);

        if(regex.test(viewValue)) {
            ctrl.$setValidity('validNumber',true);
            return viewValue;
        }
        else {
            ctrl.$setValidity('validNumber',false);
            return undefined;
        }
    };

    ctrl.$parsers.unshift(verificationFunction);
    verificationFunction();
}
于 2013-06-09T17:44:24.197 回答
0

在 (>=) angular 1.3.1 版本发布后,您可以按照角度验证指令样式(例如requiredmaxlength )以稍微正确的方式实现该行为。

在这种情况下,您必须将验证器附加为数组的属性,并且$validators不再需要:$parsers$formatters

var app = angular.module('test', []);

app
  .directive('validNumber', function() {
    return {
      require: "ngModel",
      link: function(scope, elm, attrs, ctrl) {
        var regex = /^\d+$/;

        ctrl.$validators['validNumber'] = function(modelValue, viewValue) {
          return regex.test(viewValue);
        };
      }
    };
  });

app.controller('NumberCtrl', NumberCtrl);

function NumberCtrl($scope) {
  $scope.amount = '5z';
};
input.ng-invalid {
  background-color: #FA787E;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>

<div ng-app="test">
  <div ng-controller="NumberCtrl">

    <div ng-form name="numberForm">
      <input name="amount"
             type="text"
             ng-model="amount"
             required 
             valid-number />
      
      <span ng-show="numberForm.amount.$error.validNumber">
        Doesn't look like an integer
      </span>
    </div>        
  </div>
</div>

于 2016-05-11T13:34:05.003 回答