【问题标题】:Validating form with mutually exclusive fields with AngularJS使用 AngularJS 验证具有互斥字段的表单
【发布时间】:2014-02-24 05:14:45
【问题描述】:

我正在使用 AngularJS 创建一个 Web 应用程序,并且我有一个包含两个字段的表单,这些字段应该被验证为互斥。我的意思是应该填写一个或另一个字段,但不能同时填写(如果两者都没有填写也有效)。我的表格(真实案例的简化模型)是这样的:

<form id="form1" name="form1">
   <p>
      <input type="text" id="field1" name="field1" ng-model="model.item1" not-both-filled="model.item2" />
   </p>
   <p>
      <input type="text" id="field2" name="field2" ng-model="model.item2" not-both-filled="model.item1" />
   </p>
   <p ng-show="form1.$invalid">not valid</p>
   <p ng-show="!form1.$invalid">valid</p>
</form>

我创建了一个这样的指令:

angular.module('myApp', []).directive('notBothFilled', function() {
    return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ctrl) {
            var validateNotBothFilled = function(value) {
                var theOther = scope.$eval(attrs.notBothFilled);
                var isNotValid = (value && value !== '' && theOther && theOther !== '');
                ctrl.$setValidity('field1', !isNotValid);
                ctrl.$setValidity('field2', !isNotValid);
                return value;
            };

            ctrl.$parsers.unshift(validateNotBothFilled);
            ctrl.$formatters.unshift(validateNotBothFilled);

        }
    };
});

但是,这有以下问题:

  1. 填写字段 1
  2. 填写字段 2
  3. 表单无效
  4. 空字段 1
  5. 表格应该有效,但无效

如果我改为清空 field2,则行为是正确的。

对不起,我仍然很少有 AngularJS 经验(而且英语不是我的母语),但有人可以告诉我:

  1. 这样的指令通常是验证 AngularJS 中互斥字段的正确方法吗?
  2. 我的代码有什么问题,如果我清空任何字段,如何使表单再次有效?

我还有一个 JS 小提琴:http://jsfiddle.net/k6ps/7vCZg/

真诚地, k6ps

【问题讨论】:

    标签: javascript html angularjs validation


    【解决方案1】:

    你的主要问题是这两行:

    ctrl.$setValidity('field1', !isNotValid);
    ctrl.$setValidity('field2', !isNotValid);
    

    这两行实际上设置了同一个输入字段的2个自定义有效性,你需要以某种方式获取另一个输入字段的ngModelController来设置其有效性

    试试这个:

    <form id="form1" name="form1">
        <p>
            <input type="text" id="field1" name="field1" ng-model="model.item1" not-both-filled="field2" form="form1"/> 
        //I pass the field name instead and also the form where these inputs are defined.
        </p>
        <p>
            <input type="text" id="field2" name="field2" ng-model="model.item2" not-both-filled="field1" form="form1"/>
        </p>
        <p ng-show="form1.$invalid">not valid</p>
        <p ng-show="!form1.$invalid">valid</p>
    </form>
    

    JS:

    angular.module('myApp', []).directive('notBothFilled', function() {
        return {
            require: 'ngModel',
            link: function(scope, elem, attrs, ctrl) {
                var validateNotBothFilled = function(value) {
                    var form = scope[attrs.form];
                    var theOther = form[attrs.notBothFilled];
                    var isNotValid = (value && value !== '' && theOther.$modelValue && theOther.$modelValue !== '');
                    ctrl.$setValidity('field', !isNotValid);//set validity of the current element
                    theOther.$setValidity('field', !isNotValid);//set validity of the other element.
                    return value;
                };
    
                ctrl.$parsers.unshift(validateNotBothFilled);
    
            }
        };
    });
    

    DEMO

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多