如何强制执行角度验证指令?

时间:2013-06-02 17:29:36

标签: validation angularjs

我已经为我的表单创建了验证指令。 它基本上根据来自另一个字段的数据验证字段值。

完美无缺: - )

我的问题是,如果在执行验证后其他字段发生更改,则验证将不会再次运行。

var myApp = angular.module('myApp', [])

.directive('validateInteger', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {
          var int1val = scope.int1;
          scope.int2valid = (viewValue > int1val) ? "valid" : undefined;
          if (scope.int2valid == "valid") {
              ctrl.$setValidity('higher', true);
              return viewValue;
          } else {
              ctrl.$setValidity('higher', false);
              return undefined;
        }
      });
    }
  };
});

jsfiddle:http://jsfiddle.net/hanspc/vCFFQ/

2 个答案:

答案 0 :(得分:3)

明确引用指令中的某些字段是一个非常糟糕的主意。正如您所看到的,这有很多缺点:不可移植性,代码重复,脆弱性......

做这样的事情:

<input type="text" ng-model="int2" validate-greater-integer="int1" />

并且:

myApp.directive('validateGreaterInteger', function() {
    return {
    require: 'ngModel',
    scope: {
        otherInteger : '=validateGreaterInteger',
    }
    link: function(scope, elm, attrs, ctrl) {
        ctrl.$parsers.unshift(function(viewValue) {
        if (viewValue > scope.otherInteger) {
            ctrl.$setValidity('higher', true);
            return viewValue;
        } else {
            ctrl.$setValidity('higher', false);
            return undefined;
        }
    }
});

然后你可以简单地做the typical state control(参见“绑定到表单和控制状态”一节的例子)。

请注意,在这种情况下,您还可以更简单地使用input[number]及其min参数。


在评论讨论后进行编辑:

嗯,NgModelController.$parsers中的函数显然只有在模型内容发生变化时才会被调用。您要做的是在int1int2更改时进行验证。所以就这样做:-):

link: function(scope, elm, attrs, ctrl) {
    scope.$watch('data', function (data) {
      if (data.int2 > data.int1) {
          ctrl.$setValidity('higher', true);
          return data.int2;
      } else {
          ctrl.$setValidity('higher', false);
          return undefined;
    }
  }, true);

使用你自己的验证变量(你的小提琴中的int2valid)也很奇怪。请使用form.int2.$error.higher,{{1}}。

答案 1 :(得分:2)

也许更简单的解决方案是使用观察者甚至是错误范围内的ng-show方向内的表达式。

在ng-show指令中使用表达式将是这样的:

<span ng-show="int1 > int2" style="color: red; display:none">   

否则,您可以观察模型int1和int2中的更改并比较它们的值:

$scope.$watch('int1+int2', function () {
    if($scope.int1 > $scope.int2) {
        $scope.error = true;    
    }else {
        $scope.error = false;
    }
}) 

<span ng-show="error" style="color: red; display:none"> 

这是fiddle