AngularJS自定义表单验证

点击打开链接

Angular实现了大部分常用的HTML5的表单控件的类型(text, number, url, email, date, radio, checkbox),也实现了很多指令做为验证(required, pattern, minlength, maxlength, min, max)。

在自定义的指令中,我们可以添加我们的验证方法到ngModelController$validators对象上。为了取得这个controller对象,我们需要requirengModel指令。

$validators对象上的每个方法都接收modelValueviewValue两个值做为参数。在你绑定的验证方法返回一个值(true,false)之后,Angular会在内部调用$setValidity方法。验证会在每一次输入框的值改变($setViewValue被调用)或者模型的值改变。验证发生在$parsers和$formatters成功运行之后,验证不通过的项会做为ngModelController.$error的属性存储起来。

另外,在这个controller对象上,还有一个$asyncValidators对象,如果你的验证是异步的,则需要加验证附加在这个对象上,比如说用户注册时输入手机号,我们需要在后端验证该手机号是否已经注册,这个验证方法必须return一个promise对象,然后在验证通过时调用延迟对象的resolve,失败时调用reject,还未完成的异步的验证存储在ngModelController.$pending中。


例如(注意其中的user对象,只有验证通过了,才会将值绑定到模型上):

[html]  view plain  copy
  1. <form name="register_form" ng-submit="save()">  
  2.     <div class="form-group">  
  3.         <label for="phoneNumber">  
  4.             手机号(不能重复):  
  5.         </label>  
  6.         <input type="text" class="form-control" ng-model="user.phoneNumber" id="phoneNumber" name="phoneNumber" required phone>  
  7.     </div>  
  8.     <div class="form-group">  
  9.         <label for="username">  
  10.             用户名(必须大于五位):  
  11.         </label>  
  12.         <input type="text" class="form-control" ng-model="user.username" id="username" required username>  
  13.     </div>  
  14.     <button class="btn btn-block btn-primary" type="submit">提交</button>  
  15. </form>  
  16. <h3>用户对象</h3>  
  17. <pre>  
  18.     {{ user | json }}  
  19. </pre>  

[javascript]  view plain  copy
  1. 'use strict';  
  2. angular.module('app', [])  
  3.   
  4. .directive('phone'function ($q, $http) {  
  5.     return {  
  6.         require: 'ngModel',  
  7.         link: function (scope, ele, attrs, ctrl) {  
  8.             ctrl.$asyncValidators.phone = function (modelValue, viewValue) {  
  9.                 var d = $q.defer();  
  10.                 $http.get('phone.json')  
  11.                 .success(function (phoneList) {  
  12.                     if (phoneList.indexOf(parseInt(modelValue)) >= 0) {  
  13.                         d.reject();  
  14.                     } else {  
  15.                         d.resolve();  
  16.                     }  
  17.                 });  
  18.                 return d.promise;  
  19.             }  
  20.         }  
  21.     }  
  22. })  
  23.   
  24. .directive('username'function ($q, $http) {  
  25.     return {  
  26.         require: 'ngModel',  
  27.         link: function (scope, ele, attrs, ctrl) {  
  28.             ctrl.$validators.username = function (modelValue, viewValue) {  
  29.                 if (modelValue) {  
  30.                     return modelValue.length > 5 ? true : false;  
  31.                 };  
  32.                 return false;  
  33.             }  
  34.         }  
  35.     }  
  36. })  

phone.json

[javascript]  view plain  copy
  1. [  
  2.     13758262732,  
  3.     15658898520,  
  4.     13628389818,  
  5.     18976176895,  
  6.     13518077986  
  7. ]  
效果


下面一个完整的用户注册的表单验证:

html:

[html]  view plain  copy
  1. <form name="register_form" novalidate>  
  2.             <div class="form-group">  
  3.                 <label for="username">用户名:</label>  
  4.   
  5.                 <!-- ng-pattern="/PATTERN/"确保输入项符合正则 -->  
  6.                 <input type="text" id="username" ng-model="user.username" class="form-control" name="username" required ng-pattern="/^[^#]*$/">  
  7.                 <span class="glyphicon glyphicon-ok right" ng-show="register_form.username.$valid"></span>  
  8.             </div>  
  9.             <div class="alert alert-danger" ng-show="register_form.username.$error.pattern">  
  10.                 <strong>请注意!</strong>  
  11.                 用户名不能带#号。  
  12.             </div>  
  13.             <div class="alert alert-danger" ng-show="register_form.username.$error.required && register_form.username.$touched">  
  14.                 <strong>请注意!</strong>  
  15.                 用户名不能为空。  
  16.             </div>  
  17.             <div class="form-group">  
  18.                 <label for="_password">密码:</label>  
  19.   
  20.                 <!-- ng-minlength="num"让密码不能小于最小长度 -->  
  21.                 <input type="password" id="_password" ng-model="data._password" class="form-control" required ng-minlength="8" name="_password">  
  22.                 <span class="glyphicon glyphicon-ok right" ng-show="register_form._password.$valid"></span>  
  23.             </div>  
  24.             <div class="alert alert-danger" ng-show="register_form._password.$error.minlength && register_form._password.$touched">  
  25.                 <strong>请注意!</strong>  
  26.                 密码长度不能少于八位。  
  27.             </div>  
  28.             <div class="alert alert-danger" ng-show="register_form._password.$error.required && register_form._password.$touched">  
  29.                 <strong>请注意!</strong>  
  30.                 密码不能为空。  
  31.             </div>  
  32.             <div class="form-group">  
  33.                 <label for="password">确认密码:</label>  
  34.                 <input type="password" id="password" ng-model="user.password" class="form-control" name="password" required pwd-repeat>  
  35.                 <span class="glyphicon glyphicon-ok right" ng-show="register_form.password.$valid"></span>  
  36.             </div>  
  37.             <div class="alert alert-danger" ng-show="register_form.password.$error.pwdRepeat && register_form.password.$touched">  
  38.                 <strong>请注意!</strong>  
  39.                 两次输入的密码不相同。  
  40.             </div>  
  41.             <div class="alert alert-danger" ng-show="register_form.password.$error.required && register_form.password.$touched">  
  42.                 <strong>请注意!</strong>  
  43.                 请再次输入密码。  
  44.             </div>  
  45.             <div class="form-group">  
  46.                 <label for="phone">手机号:</label>  
  47.                 <div class="row">  
  48.                     <div class="col-sm-10">  
  49.                         <input type="num" id="phone" ng-model="user.phone" name="phone" class="form-control" required ng-minlength="11" ng-maxlength="11" phone>  
  50.                     </div>  
  51.                     <div class="col-sm-2">  
  52.                         <button class="btn btn-default" type="button" ng-disabled="register_form.phone.$invalid">发送验证码</button>  
  53.                     </div>  
  54.                 </div>  
  55.                 <span class="glyphicon glyphicon-ok right" ng-show="register_form.phone.$valid"></span>  
  56.             </div>  
  57.             <div class="alert alert-danger" ng-show="register_form.phone.$error.phone">  
  58.                 <strong>请注意!</strong>  
  59.                 该手机号已注册过,可直接登录。  
  60.             </div>  
  61.             <div class="alert alert-danger" ng-show="register_form.phone.$touched && !register_form.phone.$error.phone && (register_form.phone.$error.required || register_form.phone.$error.minlength || register_form.phone.$error.maxlength)">  
  62.                 <strong>请注意!</strong>  
  63.                 请输入正确的手机号。  
  64.             </div>  
  65.             <div class="form-group">  
  66.                 <label for="code">验证码:</label>  
  67.                 <input type="text" id="code" ng-model="user.code" class="form-control" name="code" required>  
  68.                 <span class="glyphicon glyphicon-ok right" ng-show="register_form.code.$valid"></span>  
  69.             </div>  
  70.   
  71.             <!-- 在表单不合法时禁用提交按钮 -->  
  72.             <button class="btn btn-block btn-primary" type="submit" ng-disabled="register_form.$invalid" ng-click="save()">提交</button>  
  73.         </form>  
js:

[javascript]  view plain  copy
  1. 'use strict';  
  2. angular.module('app', [])  
  3. .controller('myCtrl'function ($scope) {  
  4.     $scope.data = {};  
  5.     $scope.save = function () {  
  6.         alert('保存成功!')  
  7.     }  
  8. })  
  9.   
  10. // 判断手机号是否重复  
  11. .directive('phone'function ($q, $http) {  
  12.     return {  
  13.         require: 'ngModel',  
  14.         link: function (scope, ele, attrs, ctrl) {  
  15.             ctrl.$asyncValidators.phone = function (modelValue, viewValue) {  
  16.                 var d = $q.defer();  
  17.                 $http.get('phone.json')  
  18.                 .success(function (phoneList) {  
  19.                     if (phoneList.indexOf(parseInt(modelValue)) >= 0) {  
  20.                         d.reject();  
  21.                     } else {  
  22.                         d.resolve();  
  23.                     }  
  24.                 });  
  25.                 return d.promise;  
  26.             }  
  27.         }  
  28.     }  
  29. })  
  30.   
  31. // 验证两次输入的密码是否相同的自定义验证  
  32. .directive('pwdRepeat'function () {  
  33.     return {  
  34.         require: 'ngModel',  
  35.         link: function (scope, ele, attrs, ctrl) {  
  36.   
  37.             ctrl.$validators.pwdRepeat = function (modelValue) {  
  38.   
  39.                 // 当值为空时,通过验证,因为有required  
  40.                 if (ctrl.$isEmpty(modelValue)) {  
  41.                     return true;  
  42.                 }  
  43.   
  44.                 return modelValue === scope.data._password ? true : false;  
  45.             }  
  46.         }  
  47.     }  
  48. })  
css:

[css]  view plain  copy
  1. .form-group {  
  2.     positionrelative;  
  3. }  
  4. .right {  
  5.     positionabsolute;  
  6.     right: 10px;  
  7.     top: 34px;  
  8.     colorgreen;  
  9. }  
phone.json:

[javascript]  view plain  copy
  1. [  
  2.     13758262732,  
  3.     15658898520,  
  4.     13628389818,  
  5.     18976176895,  
  6.     13518077986  
  7. ]  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值