我有一个表单的输入字段和验证设置通过添加所需的属性等。但对于某些字段,我需要做一些额外的验证。我如何“输入”到FormController控制的验证?

自定义验证可以是类似于“如果这3个字段被填写,那么这个字段是必需的,需要以特定的方式格式化”。

FormController中有一个方法。$setValidity,但这看起来不像一个公共API,所以我宁愿不使用它。创建一个自定义指令并使用NgModelController看起来是另一种选择,但基本上需要我为每个自定义验证规则创建一个指令,这是我不想要的。

实际上,从控制器标记字段为无效(同时也保持FormController同步)可能是我在最简单的场景中需要完成的工作,但我不知道如何做到这一点。


当前回答

Angular-UI的项目包含一个ui-validate指令,它可能会帮助你做到这一点。它让你指定一个函数来调用来进行验证。

看看演示页面:http://angular-ui.github.com/,向下搜索Validate标题。

从演示页面:

<input ng-model="email" ui-validate='{blacklist : notBlackListed}'>
<span ng-show='form.email.$error.blacklist'>This e-mail is black-listed!</span>

然后在你的控制器中:

function ValidateCtrl($scope) {
  $scope.blackList = ['bad@domain.example','verybad@domain.example'];
  $scope.notBlackListed = function(value) {
    return $scope.blackList.indexOf(value) === -1;
  };
}

其他回答

Angular-UI的项目包含一个ui-validate指令,它可能会帮助你做到这一点。它让你指定一个函数来调用来进行验证。

看看演示页面:http://angular-ui.github.com/,向下搜索Validate标题。

从演示页面:

<input ng-model="email" ui-validate='{blacklist : notBlackListed}'>
<span ng-show='form.email.$error.blacklist'>This e-mail is black-listed!</span>

然后在你的控制器中:

function ValidateCtrl($scope) {
  $scope.blackList = ['bad@domain.example','verybad@domain.example'];
  $scope.notBlackListed = function(value) {
    return $scope.blackList.indexOf(value) === -1;
  };
}

@ synergy我认为@blesh应该把函数验证如下

function validate(value) {
    var valid = blacklist.indexOf(value) === -1;
    ngModel.$setValidity('blacklist', valid);
    return valid ? value : undefined;
}

ngModel.$formatters.unshift(validate);
ngModel.$parsers.unshift(validate);

你可以在你的验证场景中使用ng-required(“如果这3个字段都填写了,那么这个字段是必须的”:

<div ng-app>
    <input type="text" ng-model="field1" placeholder="Field1">
    <input type="text" ng-model="field2" placeholder="Field2">
    <input type="text" ng-model="field3" placeholder="Field3">
    <input type="text" ng-model="dependentField" placeholder="Custom validation"
        ng-required="field1 && field2 && field3">
</div>

编辑:下面添加了关于ngMessages (>= 1.3.X)的信息。

标准表单验证消息(1.0.;X及以上)

因为这是你谷歌“Angular Form Validation”得到的最多的结果之一,现在,我想为那些从那里来的人添加另一个答案。

FormController中有一个方法。$setValidity,但这看起来不像一个公共API,所以我宁愿不使用它。

这是“公开的”,不用担心。使用它。这就是它的作用。如果不打算使用它,Angular开发人员会在闭包中对它进行私有化。

要进行自定义验证,如果你不想像其他答案建议的那样使用Angular-UI,你可以简单地滚动你自己的验证指令。

app.directive('blacklist', function (){ 
   return {
      require: 'ngModel',
      link: function(scope, elem, attr, ngModel) {
          var blacklist = attr.blacklist.split(',');

          //For DOM -> model validation
          ngModel.$parsers.unshift(function(value) {
             var valid = blacklist.indexOf(value) === -1;
             ngModel.$setValidity('blacklist', valid);
             return valid ? value : undefined;
          });

          //For model -> DOM validation
          ngModel.$formatters.unshift(function(value) {
             ngModel.$setValidity('blacklist', blacklist.indexOf(value) === -1);
             return value;
          });
      }
   };
});

下面是一些用法的例子:

<form name="myForm" ng-submit="doSomething()">
   <input type="text" name="fruitName" ng-model="data.fruitName" blacklist="coconuts,bananas,pears" required/>
   <span ng-show="myForm.fruitName.$error.blacklist">
      The phrase "{{data.fruitName}}" is blacklisted</span>
   <span ng-show="myForm.fruitName.$error.required">required</span>
   <button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>

注:在1.2。X,最好用ng-if代替上面的ng-show

这里是一个强制性的活塞链接

此外,我还写了一些关于这个主题的博客文章,内容更详细一些:

Angular表单验证

自定义验证指令

编辑:在1.3.X中使用ngMessages

现在你可以使用ngMessages模块来代替ngShow来显示错误消息。它实际上可以与任何东西一起工作,它不一定是一个错误消息,但这里是基本的:

包含<script src="angular-messages.js"></script> .js 在模块声明中引用ngMessages: Var app = angular。模块(“myApp”,[' ngMessages ']); 添加适当的标记: <表单名称= " personForm " > <input type="email" name="email" ng-model="person. "电子邮件“要求/ > < div ng-messages = " personForm.email。美元错误”> 需要< div ng-message = "需要" > < / div > <div ng-message="email">无效邮件</div> < / div > > < /形式

在上面的标记中,ng-message="personForm.email。$error"基本上指定ng-message子指令的上下文。然后ng-message="required"和ng-message="email"指定要监视的上下文属性。最重要的是,它们还指定了办理入住的顺序。它在列表中发现的第一个“真实”的信息获胜,它将显示该信息,而不显示其他信息。

ngMessages示例的plunker

我最近创建了一个指令,允许基于表达式的角表单输入失效。任何有效的角表达式都可以使用,并且它支持使用对象表示法自定义验证键。用angular v1.3.8测试

        .directive('invalidIf', [function () {
        return {
            require: 'ngModel',
            link: function (scope, elm, attrs, ctrl) {

                var argsObject = scope.$eval(attrs.invalidIf);

                if (!angular.isObject(argsObject)) {
                    argsObject = { invalidIf: attrs.invalidIf };
                }

                for (var validationKey in argsObject) {
                    scope.$watch(argsObject[validationKey], function (newVal) {
                        ctrl.$setValidity(validationKey, !newVal);
                    });
                }
            }
        };
    }]);

你可以这样使用它:

<input ng-model="foo" invalid-if="{fooIsGreaterThanBar: 'foo > bar',
                                   fooEqualsSomeFuncResult: 'foo == someFuncResult()'}/>

或者通过传入一个表达式(它将被赋予默认的validationKey " invalididif ")

<input ng-model="foo" invalid-if="foo > bar"/>