如何使用ng-repeat和使用ng-form创建的动态表单元素验证动态规则?

时间:2014-01-07 21:26:06

标签: javascript validation angularjs angularjs-ng-repeat angularjs-ng-form

我有一个动态生成任意数量文本输入的下拉列表,所有文本输入都有不同的验证规则(最小/最大长度,模式等)。根据其他几个stackoverflow问题,即。 (How to validate inputs dynamically created using ng-repeat, ng-show (angular))使用ng-form模块可以让您使用动态验证创建动态表单元素。

我已经这样做了,但问题是当根据下拉列表中的选择更改文本字段的数量时,验证规则不会相应更新。例如,第一个下拉选项将生成1个文本输入,最小长度为3.第二个选项也可以生成1个文本输入,但它的最小长度为1.即使minlength规则为1,angular最终验证minlength 3,来自原始选择的文本字段。

我的问题是,这是否可能在角度而不创建某种自定义指令?另一种解决方案是只预先输出每个下拉选择的所有可能的文本元素,并使用基于下拉选择的ng-show来显示/隐藏每个集合。但是我想保持模板清洁并使用ng-repeat来动态生成它们,就像我现在一样。

我设置了一个最小的例子:

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

validationApp.controller('ValidationCtrl', ['$scope', function($scope) {
    $scope.textChoices = [
        { label: "1 line", validation: [ { minLength: 3 } ] },
        { label: "2 lines", validation: [ { minLength: 1 }, { minLength: 3 } ] },
        { label: "3 lines", validation: [ { minLength: 2 }, { minLength: 2 }, { minLength: 3 } ] }
    ];
    $scope.choice = $scope.textChoices[0];
    $scope.text = [];
}]);

请在此处查看html和完整示例:http://jsfiddle.net/anpsince83/kBVR2/

2 个答案:

答案 0 :(得分:0)

other Stack Overflow question中所述,目前的AngularJS表单验证无法实现。但是这里有一个使用ngChange的方法:

AngularJS:

validationApp.controller('ValidationCtrl', ['$scope', function($scope) {
$scope.chkLength = function(i) {
    $scope.minBad[i] = ($scope.text[i].length < $scope.choice.validation[i].minLength);
};
$scope.minBad = {};
}]);

HTML:

        <ng-form name="textForm">
            <label>Enter Text</label>
            <input type="text"
                   name="text"
                   ng-model="text[$index]"
                   ng-change="chkLength($index)">

            Min {{ rules.minLength }} Chars

            <div class="error" ng-show="minBad[$index]">
                <small>Please enter min amount of characters.</small>
            </div>
        </ng-form>

小提琴代码:http://jsfiddle.net/kBVR2/61/

答案 1 :(得分:0)

不幸的是,使用内置验证指令看起来不太可能,正如其他人所建议的那样,我实现了一个自定义指令。

validationApp.directive('myMinlength', [function() {
    return {
        require: 'ngModel',
        scope: {
            myMinlength: '@',
            ngModel: '='
        },
        link: function(scope, elem, attrs, ctrl) {
            var minLengthValidator = function(value) {
                if (attrs.myMinlength) {
                    var minlength = attrs.myMinlength;
                    if (!ctrl.$isEmpty(value) && value.length < minlength) {
                        ctrl.$setValidity('myMinlength', false);
                    } else {
                        ctrl.$setValidity('myMinlength', true);
                    }
                } else {
                    ctrl.$setValidity('myMinlength', true);
                }
            };

            // validate when minlength attr changes
            scope.$watch('myMinlength', function() {
                minLengthValidator(scope.ngModel);
            });

            // validate when model changes
            scope.$watch('ngModel', minLengthValidator);
        }
    }
}]);