Angularjs初始表单验证与指令

时间:2013-06-09 15:41:30

标签: javascript angularjs

我有一个名为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设置为无效的clss,如果输入框初始化为首次加载页面时的值无效,例如,如果我设置$scope.amount = 'not a number' I期望输入框已经将指令应用于它,但没有乐趣。为了使not a number突出显示为无效,我必须更改输入的内容,从而触发指令。

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

这里有一个完整的代码示例;

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

3 个答案:

答案 0 :(得分: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);
    }
  };
});

Demo plunker

答案 1 :(得分:1)

您可以在链接阶段简单地调用验证功能,例如fiddle

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();
}

答案 2 :(得分:0)

在发布了角度1.3.1版本的(&gt; =)之后,您可以按照角度验证指令样式(例如requiredmaxlength)以一点点正确的方式实现该行为。

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

&#13;
&#13;
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';
};
&#13;
input.ng-invalid {
  background-color: #FA787E;
}
&#13;
<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>
&#13;
&#13;
&#13;