AngularJS表單驗證

表單

網頁中用戶於服務端交互數據的表單控件有input、select、textarea,而表單是將爲了達到一個目的(登陸、註冊等)各類控件整合到一塊兒的一個集合。
表單和其中的表單控件提供了驗證服務,可讓用戶在提交(通常在點擊類型爲submit的按鈕時提交)表單前意識到本身有非法(不符合要求,如下都將稱爲非法)的輸入。這種驗證方式(客戶端驗證)提供了比單獨的服務端驗證更好的用戶體驗,由於用戶在輸入後獲得實時的反饋,修正輸入的信息。
可是雖說客戶端驗證提供了更好的用戶體驗,可是服務端驗證也是不可或缺的,由於客戶端驗證並不可靠並且很容易被繞過。爲了編寫一個可靠的應用程序,服務端驗證是不可或缺的。css

基礎的表單

用於理解雙向數據綁定的關鍵指令是ngModel(指令在視圖中使用時須要將大寫字母裝換爲-x,例如ng-model),ngModel(ngBind)指令提供了模型與視圖之間的雙向數據綁定的方法。另外,ngModel爲其餘指令擴展其行爲提供了API(應用程序編程接口)。html

<body ng-controller="myCtrl">  
    <form name="basicForm" novalidate>  
        <div class="form-group">  
            <label for="name">姓名:</label>  
            <input type="text" id="name" ng-model="user.name" class="form-control">  
        </div>  
        <div class="form-group">  
            <label for="email">郵箱:</label>  
            <input type="email" id="email" ng-model="user.email" class="form-control">  
        </div>  
        <div class="form-group">  
            <label for="gender">性別:</label>  
            <label class="radio-inline">  
                <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="male" ng-model="user.gender"> 男  
            </label>  
            <label class="radio-inline">  
                <input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="female" ng-model="user.gender"> 女  
            </label>  
        </div>  
        <div class="text-center">  
            <button class="btn btn-success" type="submit" ng-click="save()">保存</button>  
            <button class="btn btn-danger" ng-click="reset()">重置</button>  
        </div>  
    </form>  
    <pre>  
        user:{{ user | json }}  
    </pre>  
    <pre>  
        User:{{ User | json }}  
    </pre>  
    <script>  
        angular.module('basicForm',[])  
            .controller('myCtrl',['$scope',  
                function ($scope) {  
                    $scope.User = {};  
                    $scope.save = function () {  
                        $scope.User = angular.copy($scope.user);  
                    }  
                    $scope.reset = function () {  
                        $scope.user = angular.copy($scope.User)  
                    }  
                }])  
    </script>  
</body>

1458624542_8587.gif

這裏有幾個須要注意的點:編程

  • novalidate是用來禁用瀏覽器自帶的驗證。json

  • ngModel的值不會被設置,直到經過了控件的驗證,好比說type=email必須爲xxx@xxx的形式,能夠仔細看下方user中email字段的變化。瀏覽器

  • 建議不要使用type=reset的按鈕,會將輸入框清空,但不會重置數據模型中的值,緣由未知。異步

使用css樣式

在不一樣的驗證狀態下,ngModel爲控件和表單提供了一些css類(須要在樣式表中聲明):ui

  • ng-valid:數據模型合法spa

  • ng-invalid:數據模型不合法code

  • ng-valid-[key]:每個經過$setValidity添加的合法鍵orm

  • ng-invalid-[key]:每個經過$setValidity添加的不合法的鍵

  • ng-pristine:尚未與用戶交互(輸入過)的控件

  • ng-dirty:與用戶交互過的控件

  • ng-touched:失去過焦點的控件(鼠標點上去得到,點其餘地方失去)

  • ng-untouched:沒有失去過焦點的控件

  • ng-pending:任何沒有結束(與服務端交互)的異步驗證

這裏簡單的演示ng-invalid和ng-touched
html:

<form name="basicForm" novalidate>    
    <div class="form-group">    
        <label for="name">姓名:</label>    
        <input type="text" id="name" ng-model="user.name" class="form-control" required>    
    </div>    
    <div class="form-group">    
        <label for="email">郵箱:</label>    
        <input type="email" id="email" ng-model="user.email" class="form-control">    
    </div>    
    <div class="form-group">    
        <label for="gender">性別:</label>    
        <label class="radio-inline">    
            <input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="male" ng-model="user.gender"> 男    
        </label>    
        <label class="radio-inline">    
            <input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="female" ng-model="user.gender"> 女    
        </label>  
    </div>    
    <div class="text-center">    
        <button class="btn btn-success" type="submit" ng-click="save()">保存</button>    
    </div>  
</form>

css:

.ng-invalid.form-control {  
border-color: #E96666;  
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(233, 102, 102, 0.6)  
}  
.ng-touched.form-control {  
border-color: #66E985;  
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 233, 160, 0.6)  
}

第一個輸入框由於是必須的,因此是非法的狀態,因此angular會給這個控件添加ng-invalid樣式,在輸入後變爲合法,該樣式去除,在失去焦點後ng-touched樣式添加
1459915273_5679.gif

簡單的根據表單的狀態顯示不一樣的信息

表單是FormController的一個實例,咱們能夠用表單的name屬性將表單暴露到做用域中。
類似的,一個有數據綁定(有ngModel)的表單控件也是NgModelController的實例,也能夠經過表單實例的屬性(控件的name)暴露到做用域中。
咱們能夠經過這個特性擴展咱們上一個例子:

  • 在用戶與表單控件交互後再展現錯誤信息

  • 在用戶點擊提交以後再展現錯誤信息

<form name="register_form" novalidate>  
    <div class="form-group">  
        <label for="name">姓名:</label>  
        <input type="text" ng-model="user.name" id="name" class="form-control" name="name" required>  
    </div>  
    <div class="alert alert-danger" ng-show="register_form.$error.required && (register_form.$submitted || register_form.name.$touched)">  
        <strong>注意!</strong>  
        姓名不能爲空  
    </div>  
    <div class="form-group">  
        <label for="email">email:</label>  
        <input type="email" ng-model="user.email" id="email" class="form-control" name="email">  
    </div>  
    <div class="form-group">  
        <label for="male">性別:</label>  
        <label class="radio-inline">  
            <label class="radio-inline">  
                <input type="radio" name="inlineRadioOptions" id="male" value="male" ng-model="user.gender"> 男  
            </label>  
            <label class="radio-inline">  
                <input type="radio" name="inlineRadioOptions" id="female" value="female" ng-model="user.gender"> 女  
            </label>  
        </label>  
    </div>  
    <button type="submit" class="btn btn-block btn-primary">提交</button>  
</form>

注意一下,$submitted表示是否點擊過提交(type=submit)按鈕,開發遇到問題的時候,你們也能夠把$error打印出來看下,表單和表單中的控件都有$error對象,這裏我都打印出來了
1464493952_3174.gif

換種方式觸發更新模板數據

在默認狀況下,對數據的任何改變都會促發模板的更新和表單驗證。咱們可使用ngModelOptions指令去重寫這個行爲,使只有在特定的條件下才觸發。
好比說

ng-model-options="{ updateOn: 'blur' }"

會只在表單控件失去焦點時觸發,咱們也能夠設置多個事件來觸發,只要使用空格隔開便可

ng-model-options="{ updateOn: 'mousedown blur' }"

若是想把原有的保存,只是想加一個觸發條件的話,能夠加上default在列表中

ng-model-options="{ updateOn: 'default blur' }"

一個完整點的例子:
html:

<form class="row">  
    <div class="col-sm-6">  
        <h3>促發條件: blur</h3>  
        <input type="text" class="form-control" ng-model="user.name" ng-model-options="{ updateOn: 'blur' }">  
        {{ user.name }}  
    </div>  
    <div class="col-sm-6">  
        <h3>正常</h3>  
        <input type="text" class="form-control" ng-model="user.phone">  
        {{ user.phone }}  
    </div>  
</form>

延遲的數據綁定

咱們能夠經過ngModelOptions的debounce 關鍵字來使數據綁定延遲,這個延遲對解析器,驗證和表單的屬性($dirty,$pristine等)都會生效。
寫法也很簡單

ng-model-options="{ debounce: 500 }"

ngModelOptions是能夠繼承的,因此若是有多個控件都須要這個效果,能夠在他們的父元素上添加這個指令,除非子元素重寫這個屬性。

<div class="col-sm-6" ng-model-options="{ updateOn: 'default blur', debounce: { default: 1000, blur: 0 } }">  
    <h3>促發條件: blur</h3>  
    <input type="text" class="form-control" ng-model="user.name">  
    {{ user.name }}  
</div>

至於自定義表單驗證,我會另寫一篇。剛開博客沒多久,但願你們有任何問題或者意見都在下方提出,或者加我qq 651882883。

相關文章
相關標籤/搜索