javascript
AngularJS 表单数据验证及错误信息提示
一、表單驗證基本原理
表單驗證包括兩個主題:
- 定義驗證規則,驗證數據有效性。
- 顯示驗證結果,把驗證結果以友好的方式顯示給用戶。
H5內置一些驗證功能,并會顯示內置的錯誤提示信息,先要禁用它,在<form>上加個novalidate特性。如下:
<form ng-submit=vm.submit(vm.form) ?novalidate="novalidate" >
比如驗證郵箱輸入框input,驗證兩點,一是郵箱格式合法,二是必填。
對于郵箱格式,AngularJS有個內置指令,只要設置input=email,接收輸入的時候會檢測格式是否合法,并設置有效性標志。
對于必填,可以使用HTML自帶的required,<input type="email" required="required"/>,可以使用AngularJS的ng-required,<input type="email" ng-required="true"/>,ng-required可以可以編程控制,其值可以是一個scope變量,<input type="email" ng-required="vm.needEmail"/>,而required這種HTML屬性,出現就有效不管它有沒有值。
每次用戶輸入之后,這些驗證器就會按照優先級和出現的順序依次被驗證,如果驗證全部成功,就會把輸入轉換成Model中的值,如果有一個驗證不成功,Model中的值保持原樣,并在Model上增加一個$error對象,每一個驗證器都會增加一個與驗證器同名的屬性,并值為true,如{email:true}。
要在模板上引用,需要在form和input上都指定一個名字name,這樣在$scope上就多出一個form變量,其內容如下:
? ?
主要的幾個變量解釋如下:
email字段的Model如下:
與form的幾個屬性是一樣的,意義也一樣,這里,我們主要用到$dirty/$pristine、$valid/$invalid、$error,舉個最簡單的例子:
字段多了,模板中會出現重復代碼,可以用以下的錯誤信息提示指令解決該問題。
?二、錯誤信息提示指令
angular.module('com.ngnice.app').directive('bfFieldError',function bfFieldError($compile){return {restrict:'A',//必須以屬性方式使用<input bf-field-error /> require:'ngModel',//元素上必須有個ng-model屬性,沒有就會報錯//link函數在指令初始化的時候自動執行 link:function(scope,element,attrs,ngModel){//ngModel是require定義的值var subScope= scope.$new(true);//創建一個子作用域,true為獨立作用域,不會父作用域自動繼承屬性//創建子作用域subScope下的兩個函數//判斷是否有錯誤,有錯誤就要顯示錯誤信息 subScope.hasError = function(){return ngModel.$invalid && ngModel.$dirty;//無效而且有輸入才表示有錯誤 };//獲取錯誤信息內容,直接把錯誤信息顯示到界面 subScope.errors = function(){return ngModel.$error;}; //把一段html編譯成LiveDom,并把子作用域當參數傳進去,DOM會根據subScope的變化更新自己var hint = $compile('<ul ng-if="hasError()">{{errors()}}</ul>')(subScope);//errors()內容是{email:true}//把這段DOM追加到當前元素后邊,讓他顯示出來 element.after(hint);}};});分析下,指令間協作配合機制,require屬性指定另一個指令的名稱,如上邊的rquire:"ngModel",angularjs初始化的時候,會在指令所在元素尋找指令ng-model,并取得其控制器實例,并當作link函數的第四個參數傳進去,就可以使用ngModel里邊的屬性了。
改進html部分,用ng-repeat,而且用過濾器讓提示信息更友好,見后邊的過濾器
var hint = $compile('<ul ng-if="hasError()"><li ng-repeat="(name,wrong) in errors()" ng-if="wrong">{{name|error}}</li></ul>')(subScope);三、友好提示信息的過濾器
過濾器的實質是數據轉換,格式化和篩選,這里是一個格式化函數,把Model層的數據類型轉換成View層顯示的友好信息。
angular.module('com.ngnice.app').filter('error', function(){var messages={email:'不是有效的格式的郵件地址',required:'此項不能為空'};return function(name){return messages[name]||name;};});錯誤類型以后變更多,可以把message信息提取出去,建一個Constant,改造如下
常量,專門用來存放提示信息
angular.module('com.ngnice.app').constant('Error', {email:'不是有效的格式的郵件地址',required:'此項不能為空' });過濾器,把常量Error注入到過濾器 error中
angular.module('com.ngnice.app').filter('error', function(Errors){return function(name){return Errors[name]||name;}; });?四、自定義驗證規則指令
1、密碼相同驗證指令
angular.module('com.ngnice.app').directive('bfAssertSameAs',function bfAssertSameAs(){return {restrict:'A',require:'ngModel',link:function(scope,element,attrs,ngModel){//取參數attrs傳進來的bf-assert-same-as屬性表達式,并用$eval,再比較兩個值(還有個是參數傳進去的值)是否相等。var isSame = function(value){var anotherValue = scope.$eval(attrs.bfAssertSameAs);return value === anotherValue;};ngModel.$parsers.push(function(value){ngModel.$setValidity('same',isSame(value));return isSame(value) ? value : undefined;});scope.$watch(function(){return scope.$eval(attrs.bfAssertSameAs);},function(){ngModel.$setValidity('same', isSame(ngModel.$modelValue));}}};});? html部分,同時使用了bfFieldError指令
<input id="_retypedPassword" bf-field-error type="password" ng-required="true" ng-model="vm.retypedPassword" bf-assert-same-as="vm.form.password"/>當確認密碼和密碼不同的時候,bf-field-error指令在檢查結果中顯示"same",看這句代碼
ngModel.$setValidity('same', isSame(ngModel.$modelValue));分析:
$ngModel.$parsers是一個數組,當在輸入框輸入內容的時候,都會遍歷并執行$parsers里面的函數。
$ngModel.$setValidity("same",false);設置same為無效,會設置$ngModel.$error["same"] = false; ?{"same" : false}
可以在常量中添加一項:
angular.module('com.ngnice.app').constant('Error', {email:'不是有效的格式的郵件地址',required:'此項不能為空', same:'此項必須與上一項相同' });到此時,通用性還不夠好,可以進一步,修改bf-field-error指令,讓自定義錯誤信息自己傳進去,如下:
<input id="_retypedPassword" bf-field-error="{same:'確認密碼必須與密碼相同'}" type="password" ng-required="true" ng-model="vm.retypedPassword" bf-assert-same-as="vm.form.password"/>修改bf-field-error指令代碼:
subScope.customMessages=scope.$eval(attrs.bfFieldError);//取得一個自定義消息對象{same:'確認密碼必須與密碼相同'}//把自定義消息對象customMessages傳給過濾器 var hint = $compile('<ul ng-if="hasError()"><li ng-repeat="(name,wrong) in errors()" ng-if="wrong">{{name|error:customerMessages}}</li></ul>')(subScope);
最后要修改下過濾器error:
angular.module('com.ngnice.app').filter('error', function(Errors){return function(name, customMessages){var errors = angular.extend({},Errors,customMessages);return errors[name]||name;}; });整個執行過程如下:
- 用戶輸入
- angular執行所有$parsers中的函數
- 遇到$setValidity("xxoo",false);那么就會把xxoo當做一個key設置到$ngModel.$error["xxoo"]
- 然后bf-field-error指令會ng-repeat $ngModel.$error
- error會對錯誤信息轉義
- 最后顯示錯誤的信息
轉載于:https://www.cnblogs.com/shawnhu/p/8540801.html
總結
以上是生活随笔為你收集整理的AngularJS 表单数据验证及错误信息提示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js中函数的参数为函数的情况即回调函数
- 下一篇: java线程学习第一天__低配版的卖面包