如何验证多个字段并显示唯一错误?

时间:2017-07-19 15:09:43

标签: angularjs angularjs-directive

我想针对多个字段验证控件。我想显示一个错误,指出哪个字段导致验证失败。

运行以下代码。将第一个值更改为高数字(E.G.5),验证将通过。将第一个值更改为较小的数字(2),验证将失败。

在“2”的情况下,应该有2个错误:model3,model4,因为这些模型的值高于2.同样适用于所有其他字段。

验证工作正常。我无法根据失败的特定验证规则显示正确的错误消息。

请注意,任何字段更改都必须像现在一样重新启动验证。您应该在整页视图中运行此代码段。

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

app.controller('MainCtrl', function($scope) { 
  $scope.model = {number: "1"};
  $scope.model2 = {number: "2"};
  $scope.model3 = {number: "3"};
  $scope.model4 = {number: "4"};
});

app.directive('theGreatest', function(){
    return {
        require: 'ngModel',
        restrict: 'A',
        link: function($scope, $element, $attr, ngModel) {
            var compareCollection;

            // watch the attribute to get the date we need to compare against
            $attr.$observe('theGreatest', function (val) {
                console.log('compareCollection set to: ', val);
                compareCollection = JSON.parse(val);
                ngModel.$validate();
            });

            ngModel.$validators.theGreatest = function(modelValue, viewValue) {
                 console.log('validating...', modelValue);
                 console.log('compareDate: ', compareCollection);
                    
                var pass = true;
                _.map(compareCollection, function(compare){
                  console.log('comparing value: ', compare);
                  if(modelValue < compare){
                    pass = false; 
                  }
                });
        
                console.log('validation pass', pass);
                return pass;
            };
        }
    };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
<section ng-app="app" ng-controller="MainCtrl">
<div>first: <input type="text" ng-model="model.number" the-greatest="{{[model2.number, model3.number, model4.number]}}" />
  (change me to a high number)
  </div>
<div>second: <input ng-model="model2.number" type="text" /></div>
<div>third: <input ng-model="model3.number" type="text" /></div>
<div>fourth: <input ng-model="model4.number" type="text" /></div>
  <div>validation passed if you see a value here: {{model.number}}</div>
  <div>The following errors are not implemented correctly.  The intention is to show what I am want to accomplish</div>
  <div ng-if="!model.number">ERROR: first is less than model 2</div>
  <div ng-if="!model.number">ERROR: first is less than model 3</div>
  <div ng-if="!model.number">ERROR: first is less than model 4</div>
  
  <div ng-if="!model.number">ERROR: first is required</div>
</section>

1 个答案:

答案 0 :(得分:1)

您需要将ErrorFlags数组发送到指令中,并在验证失败时将这些标记标记为false。

HTML:

<section ng-app="app" ng-controller="MainCtrl">
    <div>first: <input type="text" ng-model="model.number" the-greatest="{{[model2.number, model3.number, model4.number]}}" error-flags="errorFlags" />
    (change me to a high number)
    </div>
    <div>second: <input ng-model="model2.number" type="text" /></div>
    <div>third: <input ng-model="model3.number" type="text" /></div>
    <div>fourth: <input ng-model="model4.number" type="text" /></div>
    <div>validation passed if you see a value here: {{model.number}}</div>
    <div>The following errors are not implemented correctly.  The intention is to show what I want to accomplish</div>
    <div ng-if="!errorFlags[0]">ERROR: first is less than model 2</div>
    <div ng-if="!errorFlags[1]">ERROR: first is less than model 3</div>
    <div ng-if="!errorFlags[2]">ERROR: first is less than model 4</div>

    <div ng-if="!model.number">ERROR: first is required</div>
</section>

AngularJS代码:

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

app.controller('MainCtrl', function($scope) { 
  $scope.model = {number: "1"};
  $scope.model2 = {number: "2"};
  $scope.model3 = {number: "3"};
  $scope.model4 = {number: "4"};
  $scope.errorFlags = [true, true , true];
});

app.directive('theGreatest', function(){
    return {
        require: 'ngModel',
        restrict: 'A',
        scope: {
          errorFlags:"="
        },
        link: function(scope, element, attrs, ngModel) {
            var compareCollection;

            // watch the attribute to get the date we need to compare against
            attrs.$observe('theGreatest', function (val) {
                console.log('compareCollection set to: ', val);
                compareCollection = JSON.parse(val);
                ngModel.$validate();
            });

            ngModel.$validators.theGreatest = function(modelValue, viewValue) {
                 console.log('validating...', modelValue);
                 console.log('compareDate: ', compareCollection);
              scope.errorFlags = [true, true, true];
                    console.log("Before Validation Flags", scope.errorFlags);
                var pass = true;
              var loopVariable = 0;
                _.map(compareCollection, function(compare){
                  console.log('comparing value: ', compare);
                  if(modelValue < compare){
                    pass = false;
                    scope.errorFlags[loopVariable] = false;
                  }
                  loopVariable++;
                });
              console.log("after Validation Flags", scope.errorFlags);
                console.log('validation pass', pass);
                return pass;
            };
        }
    };
});