Angular表單驗證

來源:互聯網
上載者:User

標籤:準備工作   form   使用者   優先   clu   put   訪問   ini   $scope   

在使用 AngularJS 進行開發的時候,表單填寫是一個很常見的需求,而表單驗證又是比較讓人頭疼的部分,本文對此做一個總結。

在 Angular 的視圖中使用的 form 已經不是 HTML 中的普通 form 了,而是一個被 Angular 封裝過的指令。它可以完成普通 form 無法實現的功能,比如 form 嵌套,而且內建強大的驗證功能。

Angular 在對錶單進行校正的時候會使用 ngModelController 上的屬性,如果不設定 ng-model,則 Angular 無法知道 form.$invalid 這個值是否為真。後面在自訂驗證有對它的介紹。

本文在對錶單的驗證時使用了 ng-messages,在文章最後也有對它的介紹。

本文涉及到的源碼在 這裡,實現效果在 這裡。

原生表單驗證

在 form 層面,可以使用 ng-disabled 來控制提交按鈕的狀態,在 form 表單項全部驗證通過前不可點擊,下面介紹一下通用的表單項驗證選項。

input 驗證選項

AngularJS 的 input 標籤 內建的驗證選項有以下這些。

<input  ng-model=""  [name=""]  [required=""]  [ng-required=""]  [ng-minlength=""]  [ng-maxlength=""]  [ng-pattern=""]  [ng-change=""]>...</input>

a. 必填

<input type="text" name="myName" ng-model="username" required />

使用 ng-required 可以根據後面運算式的值設定是否 required

在不滿足 requiredform.myName.$error{required: true}

b. 長度

<input type="text" name="myName" ng-model="username" ng-minlength="2" ng-maxlength="10" />

在不滿足 ng-minlength/ng-maxlengthform.myName.$error{minlength: true, maxlength: true}

直接使用 minlength/maxlength 也有相同效果,而且 maxlength 可以設定最多輸入 x 個字元,超過之後無法再輸入。

c. 模式比對

<input type="text" name="myDesc" ng-model="desc" ng-pattern="/^[a-zA-Z]{1,20}$/" />

在不滿足 ng-patternform.myName.$error{pattern: true}

d. 其他

AngularJS 對特定格式也進行了校正。比如將 type 設定為 urlemail 等,在沒有特殊驗證要求的情況下,可以直接使用這些內建的校正,或者通過自訂指令修改 Angular 內建驗證器。不同 type 有不同的驗證選項,具體參考 AngularJS API 文檔。

CSS Classes

Angular 會根據表單狀態自動給表單和表單項添加以下幾組樣式:

  • ng-valid 驗證通過,與之相對的是 ng-invalid

  • ng-valid-[key] 通過自訂驗證器添加的驗證通過的值,與之相對的是 ng-invalid-[key]

  • ng-pristine 未互動狀態,與之相對的是 ng-dirty

  • ng-touched 未訪問狀態,與之相對的是 ng-untouched

  • ng-pending 滿足 $asyncValidators 的情況

這些在 ngModelController 的屬性中都有對應值。

根據這些 class,可以為不同狀態設定不同的樣式,比如這樣:

input.ng-valid.ng-dirty {    border-color: #78FA89;}input.ng-invalid.ng-dirty {    border-color: #FA787E;}
自訂驗證

在 AngularJS 指令入門 一文中,提到過通過 require 屬性和 controller 參數,可以實現指令之間的互動。那麼,在自訂指令中使用 require: ‘ngModel‘ 就可以使用 ngModel 指令的 controller 屬性的執行個體了。

ngModelController

ngModel 提供了資料繫結、驗證、CSS更新、資料格式化和編譯等操作。下面簡單介紹一下 ngModelController 常用的屬性和方法。

核心屬性
  1. $viewValue 視圖裡的值

  2. $modelValue 資料模型裡值

input 事件觸發的時候,$viewValue 會同步到 $modelValue 。預設情況下,這個是一旦 input 中的內容有改變就觸發。AngularJS 1.3 引入了 ng-model-options,可以讓這個同步延遲到 blur 或者延遲一定的時間之後。

<input type="text" name="username" ng-model="username" ng-model-options="{updateOn:‘blur‘}"><input type="text" name="username" ng-model="username" ng-model-options="{ debounce: 500 }">

$viewValue 的值同步到 $modelValue 時,會經過 $parsers$validators$asyncValidators 三個核心管道(後兩個是 AngularJS 1.3 以後新加的)進行處理,通過後才更新到 $modelValue 上(如果驗證器管道沒通過,不會更新)。

核心管道
  1. $parsers 改變視圖值的格式,並更新的到模型($viewValue -> $modelValue),與之相對的是 $formatters,剛好反過來。

  2. $validators 用來添加同步驗證器

  3. $asyncValidators 用來添加非同步驗證器

常用屬性
  1. $error 沒有通過的驗證器名稱及對應的錯誤資訊

  2. $valid 表單項是否都通過驗證,都通過時為 true,與之相對的是 $invalid

  3. $touched 表單項是否被訪問過,如果獲得過焦點,在失去時該值為 true,與之相對的是 $untouched

  4. $dirty 表示使用者是否和表單項互動過(比如輸入一些東西),只要有任何改變,該值為 true,與之相對的是 $pristine

常用方法
  1. $render 定義視圖具體的渲染方式

  2. $setViewValue 設定視圖值(需要手動觸發一個 $digest),使用情境是在自訂指令中監聽自訂事件(比如使用具有回調的 jQuery 外掛程式)

自訂同步驗證 & 非同步驗證

ngModelController 中講到,AngularJS 1.3 提供了驗證器管道,同步驗證只需要加到 $validators 上即可。

比如,有這樣一個常見的需求,對一個必填的名稱表單項,要求只能輸入中英文,最小長度為2位字元,那麼可以這樣實現。

指令:

app.directive(‘nameCheck‘, nameCheck);nameCheck.$inject = [‘$http‘, ‘$q‘];function nameCheck($http, $q){    var NAME_REG = /^[a-zA-Z\u4e00-\u9fa5]+$/;    return {        restrict: ‘A‘,        require: ‘ngModel‘,        link:function($scope,element,attrs,ctrl){            // 同步驗證            ctrl.$validators.char = function(modelValue, viewValue) {                var value = modelValue || viewValue;                if(!NAME_REG.test(value)){                    return false;                }                return true;            };            // 非同步驗證            ctrl.$asyncValidators.exist = function(modelValue, viewValue){                var value = modelValue || viewValue;                 var deferred = $q.defer();                $http.get(‘api/users/‘ + value).then(function(res) {                    if(res.data.isExist){                        deferred.reject(false);                    }                    deferred.resolve(true);                })                return deferred.promise;            }        }    }}

首頁面:

<form name="myForm">    <div class="form-group">        <input type="text" name="username" ng-model="username" class="form-control" name-check minlength="2" required>        <span ng-messages="myForm.username.$error" ng-messages-include="error.html" ng-show="myForm.username.$touched">            </span>    </div></form>

錯誤資訊頁面:

<span ng-message="required">必填</span><span ng-message="char">非法字元</span><span ng-message="minlength">太短了</span><span ng-message="exist">名稱已存在</span>
ngMessages

ng-messages 是 AngularJS 1.3 提供的一個用來增強模版顯示的模組,主要用在處理複雜的錯誤資訊。

在以前的版本中,如果想處理錯誤資訊的顯示,可能需要定義一堆 code 再結合複雜的 ng-if 語句來實現。而且在輸入同時滿足多條錯誤規則的情況下,無法控制錯誤資訊顯示的優先順序。這些,使用 ng-messages 可以完美解決。

準備工作
  1. 引入 angular-messages.js

  2. 添加依賴:angular.module(‘app‘, [‘ngMessages‘])

使用方法

有兩種使用方法,一是將 ng-messages 當作屬性指令使用:

<form name="myForm">    <input type="text" ng-model="field" name="myField" required minlength="5" />    <div ng-messages="myForm.myField.$error">        <div ng-message="required">必填</div>        <div ng-message="minlength">長度不夠</div>    </div></form>

這樣會按照各個錯誤資訊書寫的先後順序進行單一顯示,如果想同時顯示所有的錯誤資訊,加個 ng-messages-multiple

<div ng-messages="myForm.myField.$error" ng-messages-multiple></div>

另一種是將 ng-messages 當作元素指令使用:

<ng-messages for="myForm.myField.$error">    <ng-message when="required">必填</ng-message>    <ng-message when="minlength">長度不夠</ng-message></ng-messages>

如果很多表單項的錯誤提示資訊都一樣,也可以把錯誤資訊放在模版裡,使用 ng-messages-include 指令來引用:

<div ng-messages="myForm.username.$error" ng-messages-include="validateTemplate/error.html"></div>

錯誤模版檔案:

<div ng-message="required">必填</div><div ng-message="minlength">長度不夠</div>

更詳細的使用辦法直接看 angular-messages.js 源檔案裡面的注釋即可。

Angular表單驗證

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.