【问题标题】:How to validate against multiple fields and display a unique error?如何验证多个字段并显示唯一错误?
【发布时间】:2017-07-19 15:09:42
【问题描述】:

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

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

在“2”的情况下,应该有 2 个错误:model3、model4,因为这些模型的值高于 2。对于所有其他字段也是如此。

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

请注意,任何字段更改都必须像现在一样重新触发验证。您应该在完整页面视图中运行此 sn-p。

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>

【问题讨论】:

  • 我知道了,但它不是通用的,在指令中发送另一个标志数组,当您验证检查它第一次、第二次或第三次失败并将该标志设置为 false。它将显示味精和其他将不可见
  • @WasifKhan - 不错的主意。随意发布一个答案来演示它。我会看看社区是否想出了更通用的东西,但这可能就足够了。
  • @WasifKhan - 根据您的想法,我们可以指定错误的索引吗?在这种情况下,索引 0 可以告诉我显示“错误:第一个小于模型 2”。这行得通吗?
  • 是的,你可以这样做。但是如果你需要显示两个错误,首先是小于model2。首先小于model3!!
  • @WasifKhan - 我正在考虑以某种方式返回索引数组。在那种情况下[0,1]

标签: angularjs angularjs-directive


【解决方案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;
            };
        }
    };
});

【讨论】:

    猜你喜欢
    • 2021-08-29
    • 2020-08-12
    • 2018-04-28
    • 2014-10-30
    • 2019-06-08
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    相关资源
    最近更新 更多