5

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

它工作完美:-)

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

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/

4

2 回答 2

3

明确引用指令中的某些字段是一个非常糟糕的主意。如您所见,这有很多缺点:不可移植性、代码重复、易碎性……</p>

做这样的事情:

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

然后,您可以简单地进行典型的状态控制(请参阅“绑定到表单和控制状态”部分以获取示例)。

请注意,在这种情况下,您还可以更简单地使用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在您的 Fiddle 中)也很奇怪。请使用典型的状态控制,例如form.int2.$error.higher.

于 2013-06-02T18:56:00.223 回答
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"> 

这是一个小提琴

于 2013-06-02T19:14:41.203 回答