AngularJS验证表单数组长度

时间:2014-03-03 17:41:07

标签: javascript angularjs validation

假设我有一个具有属性favoriteColors

的模型对象
{
    ...
    favoriteColors: ['red', 'green', 'blue']
    ....
}

我用ng-repeat

将它们暴露给用户
<form name="userForm">
    ...
    <ul>
        <li ng-repeat="color in user.favoriteColors">
            <input type="text" ng-model="color" />
            <a href="" ng-click="delete(color)">remove</a>
        </li>
    </ul>
    <a href="" ng-click="add()">Add a new favorite color</a>
    ...
</form>

我希望能够检查favoriteColors字段执行此类操作的有效性

<div ng-show="userForm.favoriteColors.$error">
    You must have at least one favorite color
</div>

使用内置验证器似乎无法做到这一点,而且我不确定在哪个元素上放置自定义指令以获取ngModelController favoriteColors

3 个答案:

答案 0 :(得分:13)

我的解决方案是添加一个隐藏的输入标记和绑定数组的长度

    <form name="userForm">
      ...
      <ul>
        <li ng-repeat="color in user.favoriteColors">
          <input type="text" ng-model="color" />
          <a href="" ng-click="delete(color)">remove</a>
        </li>
      </ul>
      <a href="" ng-click="add()">Add a new favorite color</a>
      ...

      <!-- new line -->
      <input style="display:none" name="colorsLength" type="number" min=1 value="{{user.favoriteColors.length}}"/>
    </form>

因此,您可以使用userForm.colorsLength。$ error进行验证。 祝你好运!

答案 1 :(得分:11)

@Loi Pham,遗憾的是我不允许发表评论,所以我必须添加帖子。 我喜欢你的方法。但是我必须将 ng-model 添加到输入中以使验证工作:

<input style="display: none" type="number" name="length" readonly ng-model="colors.length" min="1">

答案 2 :(得分:-1)

要按照您的请求进行验证,您必须使用ng-model将颜色数组放入表单中,以便验证数组。

这是一个关于plunker的快速示例,我在ngModelController的$ parsers管道上推送验证器,它将检查颜色数组的长度。将colorRequired指令保持独立将允许您具有不需要颜色的情况。您还可以添加到该指令,因此它将在属性上采用布尔参数,以便您可以在运行时决定是否需要颜色。

http://plnkr.co/edit/yFuSXxacSW811WfZqaPC

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

app.controller('MainCtrl', function($scope) {
  $scope.colors = ['red', 'blue', 'green'];
});

app.directive("colorGroup", [function() {
    "use strict";
    return {
        restrict: 'E',
        require: 'ngModel',
        template: '<ng-form name="userForm">\
               <ul>\
               <li ng-repeat="color in model">\
              <input type="text" ng-model="color" />\
              <a href="" ng-click="delete($index)">remove</a>\
              </li>\
              </ul>\
              </ng-form>',
        link: function($scope, element, attrs, ngModelCtrl)
        {
            $scope.$watch(function(){
                return ngModelCtrl.$modelValue;
            }, function(){
                $scope.model = ngModelCtrl.$viewValue;
            });

            $scope.delete = function(idx)
            {
                        ngModelCtrl.$viewValue.splice(idx, 1);
                        ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue);
                        $scope.model = ngModelCtrl.$viewValue;
            }
        }
    }
}]);

app.directive("colorRequired", function() {
    "use strict";
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function($scope, element, attrs, ngModelCtrl)
        {
                ngModelCtrl.$setValidity('colorrequired', (ngModelCtrl.$viewValue.length > 0));

                ngModelCtrl.$parsers.push(function(viewValue) {
                    var valid = viewValue.length > 0;
                    ngModelCtrl.$setValidity('colorrequired', valid);
                    return valid ? viewValue : undefined;
                });
            }
        }
    });