AngularJS入門之數據驗證

AngularJS自帶了對錶單或控件的輸入數據進行驗證的功能,對於Html5的基礎控件均有內建的驗證器,如下列舉了全部支持的驗證類型:javascript

  • email
  • max
  • maxlength
  • min
  • minlength
  • number
  • pattern
  • required
  • url
  • date
  • datetimelocal
  • time
  • week
  • month

 

AngularJS會在元素上自動添加以下樣式:css

  • ng-valid: 驗證經過
  • ng-invalid: 驗證失敗
  • ng-valid-[key]: 由$setValidity添加的全部驗證經過的值
  • ng-invalid-[key]: 由$setValidity添加的全部驗證失敗的值
  • ng-pristine: 控件爲初始狀態
  • ng-dirty: 控件輸入值已變動
  • ng-touched: 控件已失去焦點
  • ng-untouched: 控件未失去焦點
  • ng-pending: 任何爲知足$asyncValidators的狀況

 

示例1:html

 1 <!DOCTYPE >
 2 <html>
 3 <head>
 4     <style type="text/css">
 5         .ng-invalid.ng-dirty {
 6             border-color: #FA787E;
 7         }
 8 
 9         .ng-valid.ng-dirty {
10             border-color: #78FA89;
11         }
12 
13         .ng-pristine.ng-pristine {
14             border-color: #ffd800;
15         }
16     </style>
17 
18     <script src="/Scripts/angular.js"></script>
19     <script type="text/javascript">
20         (function () {
21             var app = angular.module('validationTest', []);
22 
23             app.controller('myController', ['$scope', function ($scope) {
24                 $scope.students = [];
25 
26                 $scope.addStudent = function (stu) {
27                     $scope.students.push(stu);
28                     $scope.stu = {};
29                 };
30             }]);
31         })();
32     </script>
33 </head>
34 <body ng-app="validationTest" ng-controller="myController">
35     <form name="myForm" ng-submit="myForm.$valid && addStudent(stu)" novalidate>
36         Name:
37         <input name="name" ng-model="stu.name" required />
38         <span ng-hide="myForm.name.$pristine || myForm.name.$valid" ng-show="myForm.name.$invalid">Name is required.</span>
39         <br />
40         Age:
41         <input name="age" ng-model="stu.age" type="number" max="200" min="1" required />
42         <span ng-hide="myForm.age.$pristine || myForm.age.$valid" ng-show="myForm.age.$invalid">Age is required and should between 1-200.</span>
43         <br />
44         Sex:
45         <select name="sex" ng-model="stu.sex" required>
46             <option value="0">Male</option>
47             <option value="1">Female</option>
48         </select>
49         <span ng-hide="myForm.sex.$pristine || myForm.sex.$valid" ng-show="myForm.sex.$invalid">Sex is required.</span>
50         <br />
51         Email:
52         <input name="email" ng-model="stu.email" type="email" />
53         <span ng-hide="myForm.email.$pristine || myForm.email.$valid" ng-show="myForm.email.$invalid">Email is not correct.</span>
54         <br />
55         Blog:
56         <input name="blog" ng-model="stu.blog" type="url" />
57         <span ng-hide="myForm.blog.$pristine || myForm.blog.$valid" ng-show="myForm.blog.$invalid">Blog is not correct.</span>
58         <br />
59         Birthday:
60         <input name="birthday" ng-model="stu.birthday" type="datetime-local" />
61         <span ng-hide="myForm.birthday.$pristine || myForm.birthday.$valid" ng-show="myForm.birthday.$invalid">Birthday is not correct.</span>
62 
63         <div>myForm.$valid is {{myForm.$valid}}</div>
64         <div>myForm.$invalid is {{myForm.$invalid}}</div>
65         <div>myForm.$pristine is {{myForm.$pristine}}</div>
66         <div>myForm.$dirty is {{myForm.$dirty}}</div>
67         <div>myForm.$submitted is {{myForm.$submitted}}</div>
68 
69         <div>myForm.age.$error is {{myForm.age.$error}}</div>
70 
71         <input type="submit" value="Submit" />
72     </form>
73     <hr />
74     <div ng-repeat="stu in students">
75         <span>Name:{{ stu.name }}</span>
76         <span>Age:{{ stu.age }}</span>
77         <span>Sex:{{ stu.sex == 0 ? "Male" : "Female" }}</span>
78         <span>Email:{{ stu.email }}</span>
79         <span>Blog:{{ stu.blog }}</span>
80         <span>Birthday:{{ stu.birthday }}</span>
81         <hr />
82     </div>
83 </body>
84 </html>

 

示例1中,首先對form添加novalidate屬性來禁用form的瀏覽器默認驗證行爲:java

<form name="myForm" ng-submit="myForm.$valid && addStudent(stu)" novalidate>

 

對必填的控件添加required屬性:angularjs

<input name="name" ng-model="stu.name" required />

 

本例有2種驗證結果展現方式:api

1. 控件邊框顏色變化:瀏覽器

本文開頭已說過,AngularJS會在驗證控件後自動添加內建的樣式名稱,所以,咱們只需對這些預約義的樣式名稱添加實際的樣式代碼便可:app

 1 .ng-invalid.ng-dirty {
 2     border-color: #FA787E;
 3 }
 4 
 5 .ng-valid.ng-dirty {
 6     border-color: #78FA89;
 7 }
 8 
 9 .ng-pristine.ng-pristine {
10     border-color: #ffd800;
11 }

 

2. 文字顯示驗證失敗緣由(以name控件爲例):異步

<span ng-hide="myForm.name.$pristine || myForm.name.$valid" ng-show="myForm.name.$invalid">Name is required.</span>

 

ng-hide:當name爲初始化狀態或者經過驗證的狀態,無需顯示錯誤信息提示;async

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:

 1 <!DOCTYPE >
 2 <html>
 3 <head>
 4     <script src="/Scripts/angular.js"></script>
 5     <script type="text/javascript">
 6         (function () {
 7             var app = angular.module('customValidationTest', []);
 8 
 9             var INTEGER_REGEXP = /^\-?1\d{2}$/;
10             app.directive('myInteger', function () {
11                 return {
12                     require: 'ngModel',
13                     link: function (scope, elm, attrs, ctrl) {
14                         ctrl.$validators.myInteger = function (modelValue, viewValue) {
15                             if (ctrl.$isEmpty(modelValue)) {
16                                 return true;
17                             }
18 
19                             if (INTEGER_REGEXP.test(viewValue)) {
20                                 return true;
21                             }
22 
23                             return false;
24                         };
25                     }
26                 };
27             });
28 
29         })();
30     </script>
31 </head>
32 <body ng-app="customValidationTest">
33     <form name="myForm" ng-submit="myForm.$valid" novalidate>
34         My integer:<input name="myInteger" ng-model="custInt" my-integer required />
35         <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>
36     </form>
37 </body>
38 </html>

 

修改AngularJS的內建驗證器方法

固然若是你須要重寫AngularJS內建的驗證也是能夠的。

示例3(官方Demo):

 1 <!DOCTYPE >
 2 <html>
 3 <head>
 4     <script src="/Scripts/angular.js"></script>
 5     <script type="text/javascript">
 6         (function () {
 7             var app = angular.module('modifyBuildinValidatorTest', []);
 8 
 9             app.directive('overwriteEmail', function () {
10                 var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i;
11                 return {
12                     require: 'ngModel',
13                     restrict: '',
14                     link: function (scope, elm, attrs, ctrl) {
15                         // 僅當存在ngModel且存在email這個驗證器的時候才替換
16                         if (ctrl && ctrl.$validators.email) {
17 
18                             // 這裏將重寫AngularJS默認的email驗證器
19                             ctrl.$validators.email = function (modelValue) {
20                                 return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
21                             };
22                         }
23                     }
24                 };
25             });
26         })();
27     </script>
28 </head>
29 <body ng-app="modifyBuildinValidatorTest">
30     <form name="form" class="css-form" novalidate>
31         <div>
32             Overwritten Email:
33             <input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
34             <span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
35             Model: {{myEmail}}
36         </div>
37     </form>
38 </body>
39 </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

相關文章
相關標籤/搜索