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会对错误信息转义
- 最后显示错误的信息
AngularJS 表单数据验证及错误信息提示的更多相关文章
- SpringMVC4+thymeleaf3的一个简单实例(篇四:form表单数据验证)
关于表单数据验证有很多中方法,这里我仅介绍JSR303注解验证.JSR303仅仅是一个规范,这里我们要用到它的一个实现:hibernate-validator. 注意在spring的配置文件sprin ...
- Spring学习笔记2——表单数据验证、文件上传
在上一章节Spring学习笔记1——IOC: 尽量使用注解以及java代码中,已经搭建了项目的整体框架,介绍了IOC以及mybatis.第二节主要介绍SpringMVC中的表单数据验证以及文件上传. ...
- struts1:(Struts)ActionForm类及表单数据验证
在Struts的中央控制器中写了Struts的控制器角色,在这篇介绍下Struts的视图!Struts的视图组件:Struts框架中的视图组件主要包括:JSP页面.ActionForm类.Struts ...
- 表单数据验证方法(二)——ASP.NET后台验证
昨天写了一下关于如何在前台快捷实现表单数据验证的方法,今天接着昨天的,把后台实现数据验证的方法记录一下.先说明一下哈,我用的是asp.net,所以后台验证方法也是基于.net mvc来做的. 好了,闲 ...
- php表单数据验证类
非常好用方便的表单数据验证类 <?php //验证类 class Fun{ function isEmpty($val) { if (!is_string($val)) return false ...
- jquery表单数据验证扩展方法
/** 表单数据验证 **/ $.fn.Validform = function () { var Validatemsg = ""; var Validateflag = tru ...
- php--validate错误信息提示样式
//validate 错误信息提示样式 可以提示错误信息 可以使用jq 自带的属性改变错误的显示的位置,其中element是验证未通过的当前表单元素,error为错误后的提示信息 [注意]:放的位 ...
- TP5 错误信息提示入坑指南
查遍了百度,基本都是在 config.php 开启调试 然后还有一个错误信息提示 然后做完这些以后,很神奇的事情发生了! 那就是居然没有任何鬼用.依旧是提示页面错误!什么鬼信息都没有! 然后发现在 ...
- [oldboy-django][2深入django]form表单clean_xx, clean完成数据验证+ form错误信息
form后台生成form里面的Input标签,以及设置Input的属性 # 需求 后台生成form里面的input标签,并设置input标签的属性, class RegisterForm(Form): ...
随机推荐
- 开源防火墙(pfSense)的安装部署与配置
pfSense是一个基于FreeBSD架构的软件防火墙,通常会被安装在多网卡的主板上作为路由器或者防火墙去使用.往往这些硬件都比较廉价,高性能的配置也就1千元左右.pfSense具有商业防火墙的大部分 ...
- svn conflict问题解决办法
转自:http://www.cnblogs.com/aaronLinux/p/5521844.html 目录: 1. 同一处修改文件冲突 1.1. 解决方式一 1.2. 解决方式二 1.3. 解决总结 ...
- HISAT2+StringTie+Ballgown安装及使用流程
HISAT2+StringTie+Ballgown安装及使用流程 2015年Nature Methods上面发表了一款快速比对工具hisat,作为接替tophat和bowtie的比对工具,它具有更快的 ...
- win8+iis8+PHP5安装配置和Zend Optimizer安装教程
安装 Zend Optimizer 下载地址:http://www.onlinedown.net/soft/32228.htm 下载直接双击安装即可,安装过程要你选择 Web Server ...
- JDK 之 Java Bean 内省机制
JDK 之 Java Bean 内省机制 JDK 规范目录(https://www.cnblogs.com/binarylei/p/10200503.html) JavaBean 是一种特殊的 Jav ...
- where
(二)WHERE //where不单独使用,与match,optional match,start,with搭配 where 与match,optional match 一起用,表示约束 where ...
- Mockplus3.5.0.1新增标注功能
Mockplus3.5.0.1版本中,新增了标注功能.多种标注模式,智能生成,随时查看.原型设计效率更高. Mockplus的标注功能有以下四种模式: 1.无选中标注 在未选中任何组件时,按住Ctrl ...
- vue动态路由配置,vue路由传参
动态路由: 当我们很多个页面或者组件都要被很多次重复利用的时候,我们的路由都指向同一个组件,这时候从不同组件进入一个"共用"的组件,并且还要传参数,渲染不同的数据 这就要用到动态路 ...
- install virtualenv
$ [sudo] pip install virtualenv $ mkdir ~/envs $ virtualenv ~/envs/lsbaws/ $ cd ~/envs/lsbaws/ $ ls ...
- 【Linux】zlib安装
zlib简介 zlib是提供数据压缩用的函式库,由Jean-loup Gailly与Mark Adler所开发,初版0.9版在1995年5月1日发表.zlib使用DEFLATE算法,最初是为libpn ...