AngularJS自带了对表单或控件的输入数据进行验证的功能,对于Html5的基础控件均有内建的验证器,以下列举了所有支持的验证类型:
email
max
maxlength
min
minlength
number
pattern
required
url
date
datetimelocal
time
week
month
AngularJS会在元素上自动添加如下样式:
ng-valid
: 验证通过ng-invalid
: 验证失败ng-valid-[key]
: 由$setValidity添加的所有验证通过的值ng-invalid-[key]
: 由$setValidity添加的所有验证失败的值ng-pristine
: 控件为初始状态ng-dirty
: 控件输入值已变更ng-touched
: 控件已失去焦点ng-untouched
: 控件未失去焦点ng-pending
: 任何为满足$asyncValidators的情况
示例1:
<!DOCTYPE > <html> <head> <style type="text/css"> .ng-invalid.ng-dirty { border-color: #FA787E; } .ng-valid.ng-dirty { border-color: #78FA89; } .ng-pristine.ng-pristine { border-color: #ffd800; } </style> <script src="/Scripts/angular.js"></script> <script type="text/javascript"> (function () { var app = angular.module('validationTest', []); app.controller('myController', ['$scope', function ($scope) { $scope.students = []; $scope.addStudent = function (stu) { $scope.students.push(stu); $scope.stu = {}; }; }]); })(); </script> </head> <body ng-app="validationTest" ng-controller="myController"> <form name="myForm" ng-submit="myForm.$valid && addStudent(stu)" novalidate> Name: <input name="name" ng-model="stu.name" required /> <span ng-hide="myForm.name.$pristine || myForm.name.$valid" ng-show="myForm.name.$invalid">Name is required.</span> <br /> Age: <input name="age" ng-model="stu.age" type="number" max="200" min="1" required /> <span ng-hide="myForm.age.$pristine || myForm.age.$valid" ng-show="myForm.age.$invalid">Age is required and should between 1-200.</span> <br /> Sex: <select name="sex" ng-model="stu.sex" required> <option value="0">Male</option> <option value="1">Female</option> </select> <span ng-hide="myForm.sex.$pristine || myForm.sex.$valid" ng-show="myForm.sex.$invalid">Sex is required.</span> <br /> Email: <input name="email" ng-model="stu.email" type="email" /> <span ng-hide="myForm.email.$pristine || myForm.email.$valid" ng-show="myForm.email.$invalid">Email is not correct.</span> <br /> Blog: <input name="blog" ng-model="stu.blog" type="url" /> <span ng-hide="myForm.blog.$pristine || myForm.blog.$valid" ng-show="myForm.blog.$invalid">Blog is not correct.</span> <br /> Birthday: <input name="birthday" ng-model="stu.birthday" type="datetime-local" /> <span ng-hide="myForm.birthday.$pristine || myForm.birthday.$valid" ng-show="myForm.birthday.$invalid">Birthday is not correct.</span> <div>myForm.$valid is {{myForm.$valid}}</div> <div>myForm.$invalid is {{myForm.$invalid}}</div> <div>myForm.$pristine is {{myForm.$pristine}}</div> <div>myForm.$dirty is {{myForm.$dirty}}</div> <div>myForm.$submitted is {{myForm.$submitted}}</div> <div>myForm.age.$error is {{myForm.age.$error}}</div> <input type="submit" value="Submit" /> </form> <hr /> <div ng-repeat="stu in students"> <span>Name:{{ stu.name }}</span> <span>Age:{{ stu.age }}</span> <span>Sex:{{ stu.sex == 0 ? "Male" : "Female" }}</span> <span>Email:{{ stu.email }}</span> <span>Blog:{{ stu.blog }}</span> <span>Birthday:{{ stu.birthday }}</span> <hr /> </div> </body> </html>
示例1中,首先对form添加novalidate属性来禁用form的浏览器默认验证行为:
<form name="myForm" ng-submit="myForm.$valid && addStudent(stu)" novalidate>
对必填的控件添加required属性:
<input name="name" ng-model="stu.name" required />
本例有2种验证结果展示方式:
1. 控件边框颜色变化:
本文开头已说过,AngularJS会在验证控件后自动添加内建的样式名称,因此,我们只需对这些预定义的样式名称添加实际的样式代码即可:
.ng-invalid.ng-dirty { border-color: #FA787E; } .ng-valid.ng-dirty { border-color: #78FA89; } .ng-pristine.ng-pristine { border-color: #ffd800; }
2. 文字显示验证失败原因(以name控件为例):
<span ng-hide="myForm.name.$pristine || myForm.name.$valid" ng-show="myForm.name.$invalid">Name is required.</span>
ng-hide:当name为初始化状态或者通过验证的状态,无需显示错误信息提示;
ng-show:当name控件验证失败时,展示错误提示信息。
AngularJS还提供了一些内建的状态值,方便我们直接使用:
$dirty:内容已变更
$pristine:初始化状态
$valid:验证通过
$invalid:验证失败
$submitted:已提交
$error:所有验证失败的hash对象
$$success:所有验证通过的hash对象
$pending:所有pending(异步验证)的hash对象
form中添加ng-submit属性,并且当myForm.$valid(即myForm中包含的所有验证均通过时,该值才为true)提交表单并调用addStudent方法:
<form name="myForm" ng-submit="myForm.$valid && addStudent(stu)" novalidate>
这样,当在页面上填写完有效的信息后,我们就可以将学生对象添加到Controller的students中,并由于双向绑定的特性,最终将提交的信息同步展示到页面上。
自定义验证器
你可能也猜到了,AngularJS也为我们准备好了自定义验证的方式。AngularJS实际上是通过自定义Directive,并在link中将验证方法添加到指定控件的$validators中, 在$validators中定义的对象必须有modelValue和viewValue两个参数,AngluarJS会在底层调用$setValidity来验证它。
我们看一个简单的例子,自定义验证Directive:myInteger(my-integer),输入值必须是以“1”开头,并为3位数字。
示例2:
<!DOCTYPE > <html> <head> <script src="/Scripts/angular.js"></script> <script type="text/javascript"> (function () { var app = angular.module('customValidationTest', []); var INTEGER_REGEXP = /^\-?1\d{2}$/; app.directive('myInteger', function () { return { require: 'ngModel', link: function (scope, elm, attrs, ctrl) { ctrl.$validators.myInteger = function (modelValue, viewValue) { if (ctrl.$isEmpty(modelValue)) { return true; } if (INTEGER_REGEXP.test(viewValue)) { return true; } return false; }; } }; }); })(); </script> </head> <body ng-app="customValidationTest"> <form name="myForm" ng-submit="myForm.$valid" novalidate> My integer:<input name="myInteger" ng-model="custInt" my-integer required /> <span ng-hide="myForm.myInteger.$pristine || myForm.myInteger.$valid" ng-show="myForm.myInteger.$invalid">My integer is required and should be the value 1xx.</span> </form> </body> </html>
修改AngularJS的内建验证器方法
当然如果你需要重写AngularJS内建的验证也是可以的。
示例3(官方Demo):
<!DOCTYPE > <html> <head> <script src="/Scripts/angular.js"></script> <script type="text/javascript"> (function () { var app = angular.module('modifyBuildinValidatorTest', []); app.directive('overwriteEmail', function () { var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i; return { require: 'ngModel', restrict: '', link: function (scope, elm, attrs, ctrl) { // 仅当存在ngModel且存在email这个验证器的时候才替换 if (ctrl && ctrl.$validators.email) { // 这里将重写AngularJS默认的email验证器 ctrl.$validators.email = function (modelValue) { return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue); }; } } }; }); })(); </script> </head> <body ng-app="modifyBuildinValidatorTest"> <form name="form" class="css-form" novalidate> <div> Overwritten Email: <input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" /> <span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br> Model: {{myEmail}} </div> </form> </body> </html>
在创建Directive:overwriteEmail并定义它的行为时,首先判断是否当前控件存在,且控件上已定义了email这个验证器,若存在则改写其验证。
本例中,改写后的email验证,将使以@example.com为后缀的email地址才能通过验证。
本篇讲述了AngularJS的控件验证方式以及自定义验证器,学会了使用验证器,我们就可以控制页面输入数据的合法性了,这样,我们的页面逻辑就更加完善了。
参考资料
AngularJS官方文档:https://docs.angularjs.org/guide/forms
CodeSchool快速入门视频:http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro
原文:http://www.cnblogs.com/wushangjue/p/4527487.html