AngularJS自定義表單驗證

Angular實現了大部分經常使用的HTML5的表單控件的類型(text, number, url, email, date, radio, checkbox),也實現了不少指令作爲驗證(required, pattern, minlength, maxlength, min, max)。
在自定義的指令中,咱們能夠添加咱們的驗證方法到ngModelController的$validators對象上。爲了取得這個controller對象,咱們須要requirengModel指令。
在$validators對象上的每一個方法都接收modelValue和viewValue兩個值作爲參數。在你綁定的驗證方法返回一個值(true,false)以後,Angular會在內部調用$setValidity方法。驗證會在每一次輸入框的值改變($setViewValue被調用)或者模型的值改變。驗證發生在$parsers和$formatters成功運行以後,驗證不經過的項會作爲ngModelController.$error的屬性存儲起來。
另外,在這個controller對象上,還有一個$asyncValidators對象,若是你的驗證是異步的,則須要加驗證附加在這個對象上,好比說用戶註冊時輸入手機號,咱們須要在後端驗證該手機號是否已經註冊,這個驗證方法必須return一個promise對象,而後在驗證經過時調用延遲對象的resolve,失敗時調用reject,還未完成的異步的驗證存儲在ngModelController.$pending中。html

例如(注意其中的user對象,只有驗證經過了,纔會將值綁定到模型上):json

<form name="register_form" ng-submit="save()">  
    <div class="form-group">  
        <label for="phoneNumber">  
            手機號(不能重複):  
        </label>  
        <input type="text" class="form-control" ng-model="user.phoneNumber" id="phoneNumber" name="phoneNumber" required phone>  
    </div>  
    <div class="form-group">  
        <label for="username">  
            用戶名(必須大於五位):  
        </label>  
        <input type="text" class="form-control" ng-model="user.username" id="username" required username>  
    </div>  
    <button class="btn btn-block btn-primary" type="submit">提交</button>  
</form>  
<h3>用戶對象</h3>  
<pre>  
    {{ user | json }}  
</pre>
'use strict';  
angular.module('app', [])  
  
.directive('phone', function ($q, $http) {  
    return {  
        require: 'ngModel',  
        link: function (scope, ele, attrs, ctrl) {  
            ctrl.$asyncValidators.phone = function (modelValue, viewValue) {  
                var d = $q.defer();  
                $http.get('phone.json')  
                .success(function (phoneList) {  
                    if (phoneList.indexOf(parseInt(modelValue)) >= 0) {  
                        d.reject();  
                    } else {  
                        d.resolve();  
                    }  
                });  
                return d.promise;  
            }  
        }  
    }  
})  
  
.directive('username', function ($q, $http) {  
    return {  
        require: 'ngModel',  
        link: function (scope, ele, attrs, ctrl) {  
            ctrl.$validators.username = function (modelValue, viewValue) {  
                if (modelValue) {  
                    return modelValue.length > 5 ? true : false;  
                };  
                return false;  
            }  
        }  
    }  
})
[  
    13758262732,  
    15658898520,  
    13628389818,  
    18976176895,  
    13518077986  
]

效果:
1464605246_4922.gif後端

下面一個完整的用戶註冊的表單驗證:
html:promise

<form name="register_form" novalidate>  
            <div class="form-group">  
                <label for="username">用戶名:</label>  
  
                <!-- ng-pattern="/PATTERN/"確保輸入項符合正則 -->  
                <input type="text" id="username" ng-model="user.username" class="form-control" name="username" required ng-pattern="/^[^#]*$/">  
                <span class="glyphicon glyphicon-ok right" ng-show="register_form.username.$valid"></span>  
            </div>  
            <div class="alert alert-danger" ng-show="register_form.username.$error.pattern">  
                <strong>請注意!</strong>  
                用戶名不能帶#號。  
            </div>  
            <div class="alert alert-danger" ng-show="register_form.username.$error.required && register_form.username.$touched">  
                <strong>請注意!</strong>  
                用戶名不能爲空。  
            </div>  
            <div class="form-group">  
                <label for="_password">密碼:</label>  
  
                <!-- ng-minlength="num"讓密碼不能小於最小長度 -->  
                <input type="password" id="_password" ng-model="data._password" class="form-control" required ng-minlength="8" name="_password">  
                <span class="glyphicon glyphicon-ok right" ng-show="register_form._password.$valid"></span>  
            </div>  
            <div class="alert alert-danger" ng-show="register_form._password.$error.minlength && register_form._password.$touched">  
                <strong>請注意!</strong>  
                密碼長度不能少於八位。  
            </div>  
            <div class="alert alert-danger" ng-show="register_form._password.$error.required && register_form._password.$touched">  
                <strong>請注意!</strong>  
                密碼不能爲空。  
            </div>  
            <div class="form-group">  
                <label for="password">確認密碼:</label>  
                <input type="password" id="password" ng-model="user.password" class="form-control" name="password" required pwd-repeat>  
                <span class="glyphicon glyphicon-ok right" ng-show="register_form.password.$valid"></span>  
            </div>  
            <div class="alert alert-danger" ng-show="register_form.password.$error.pwdRepeat && register_form.password.$touched">  
                <strong>請注意!</strong>  
                兩次輸入的密碼不相同。  
            </div>  
            <div class="alert alert-danger" ng-show="register_form.password.$error.required && register_form.password.$touched">  
                <strong>請注意!</strong>  
                請再次輸入密碼。  
            </div>  
            <div class="form-group">  
                <label for="phone">手機號:</label>  
                <div class="row">  
                    <div class="col-sm-10">  
                        <input type="num" id="phone" ng-model="user.phone" name="phone" class="form-control" required ng-minlength="11" ng-maxlength="11" phone>  
                    </div>  
                    <div class="col-sm-2">  
                        <button class="btn btn-default" type="button" ng-disabled="register_form.phone.$invalid">發送驗證碼</button>  
                    </div>  
                </div>  
                <span class="glyphicon glyphicon-ok right" ng-show="register_form.phone.$valid"></span>  
            </div>  
            <div class="alert alert-danger" ng-show="register_form.phone.$error.phone">  
                <strong>請注意!</strong>  
                該手機號已註冊過,可直接登陸。  
            </div>  
            <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)">  
                <strong>請注意!</strong>  
                請輸入正確的手機號。  
            </div>  
            <div class="form-group">  
                <label for="code">驗證碼:</label>  
                <input type="text" id="code" ng-model="user.code" class="form-control" name="code" required>  
                <span class="glyphicon glyphicon-ok right" ng-show="register_form.code.$valid"></span>  
            </div>  
  
            <!-- 在表單不合法時禁用提交按鈕 -->  
            <button class="btn btn-block btn-primary" type="submit" ng-disabled="register_form.$invalid" ng-click="save()">提交</button>  
        </form>
'use strict';  
angular.module('app', [])  
.controller('myCtrl', function ($scope) {  
    $scope.data = {};  
    $scope.save = function () {  
        alert('保存成功!')  
    }  
})  
  
// 判斷手機號是否重複  
.directive('phone', function ($q, $http) {  
    return {  
        require: 'ngModel',  
        link: function (scope, ele, attrs, ctrl) {  
            ctrl.$asyncValidators.phone = function (modelValue, viewValue) {  
                var d = $q.defer();  
                $http.get('phone.json')  
                .success(function (phoneList) {  
                    if (phoneList.indexOf(parseInt(modelValue)) >= 0) {  
                        d.reject();  
                    } else {  
                        d.resolve();  
                    }  
                });  
                return d.promise;  
            }  
        }  
    }  
})  
  
// 驗證兩次輸入的密碼是否相同的自定義驗證  
.directive('pwdRepeat', function () {  
    return {  
        require: 'ngModel',  
        link: function (scope, ele, attrs, ctrl) {  
  
            ctrl.$validators.pwdRepeat = function (modelValue) {  
  
                // 當值爲空時,經過驗證,由於有required  
                if (ctrl.$isEmpty(modelValue)) {  
                    return true;  
                }  
  
                return modelValue === scope.data._password ? true : false;  
            }  
        }  
    }  
})
form-group {  
    position: relative;  
}  
.right {  
    position: absolute;  
    right: 10px;  
    top: 34px; 
    color: green';
}

1464666664_5384.gif

相關文章
相關標籤/搜索