一、表单验证基本原理

  表单验证包括两个主题:

  • 定义验证规则,验证数据有效性。
  • 显示验证结果,把验证结果以友好的方式显示给用户。

  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 表单数据验证及错误信息提示相关推荐

  1. ThinkPHP5表单令牌+表单数据验证验证规则

    转:http://blog.163.com/zhuxun_why/blog/static/26813905020171861417642/ 表单验证真的很简单 相比较yii的表单验证tp做的很人性 也 ...

  2. ActionForm类及表单数据验证

    在Struts的中央控制器中写了Struts的控制器角色,在这篇介绍下Struts的视图! Struts的视图组件: Struts框架中的视图组件主要包括: JSP页面. ActionForm类. S ...

  3. vant ui 表单验证不通过信息提示的消除

    vant ui 表单验证不通过信息提示的消除 在使用vant表单验正消除表单不通过的信息时候可以个van-form 标签里加个 :key="formKey" , 我有尝试过使用:k ...

  4. 前端/后端 - 表单数据验证 - 个人实践

    1.应用场景 主要用于前端/后端的表单数据验证. 由于在之前的老项目中开发使用, 便使用了这种方式, 但是最终没有被采用.  具体的细节已经有些遗忘了, 但是依然可以作为参考. 2.学习/操作 语言: ...

  5. PHP 代码实现表单数据验证类 整理的各种情况

    这篇文章主要介绍了PHP代码实现表单数据验证类,需要的朋友可以参考下 下面通过一段PHP代码实现表单数据验证类,具体介绍如下: 非常好用方便的表单数据验证类 --------------------- ...

  6. PHP代码实现表单数据验证类

    下面通过一段PHP代码实现表单数据验证类,具体介绍如下: 非常好用方便的表单数据验证类 <?php //验证类 class Fun{ function isEmpty($val) { if (! ...

  7. php表单数据验证类

    非常好用方便的表单数据验证类 <?php //验证类 class Fun{ function isEmpty($val) { if (!is_string($val)) return false ...

  8. freemarker模板引擎,页面404,没有任何错误信息提示

    一.问题描述 freemarker模板引擎,页面404,没有任何错误信息提示,如下图所示,404首先排除页面是否存在,这个肯定是存在的,在一个排除下路径是否写错了,这个也没有问题,前面都能访问好好的, ...

  9. 数据验证html,JavaScript 表单数据验证

    JavaScript 表单 HTML 表单验证可以通过 JavaScript 来完成. HTML 表单验证也可以通过浏览器来自动完成. 如果表单字段 (fname) 的值为空, required 属性 ...

最新文章

  1. 手撸 webpack4.x 配置(一)
  2. vs debug 模式生成的exe 另一台电脑_神秘的 _DEBUG 宏从何处来?
  3. Oracle Sql 语法收集.
  4. 一站式VDI部署教程(3)配置存储分层和重复数据删除功能
  5. 从零开始玩转JMX(二)——Condition
  6. 人工智能中的局部搜索算法
  7. php表示昨天_php输出各种时间代码表示
  8. 山东济南站见面会完美收官
  9. Scrum Meeting day 2
  10. ENVI5.3.1使用Landsat 8影像进行NDVI计算实例操作
  11. 泛微OA “低代码“开发-流程表单
  12. CUMCM 2021-B:乙醇偶合制备C4烯烃(1)
  13. 戴尔计算机恢复,DELL计算机恢复镜像问题(已解决)
  14. 效果降临日历2009
  15. 盘点关于程序员的那些经典案例
  16. 迪杰斯特拉和弗洛伊德算法
  17. 风控数据来源及分析技巧
  18. GEF(Graphical Editing Framework)介绍
  19. 工业环境下,嵌入式主板的选择要考虑哪些?
  20. 漏洞分析丨HEVD-0x8.IntegerOverflow[win7x86]

热门文章

  1. mysql 开发权限_mysql权限管理
  2. 华为鸿蒙os手机图片,【图片】华为鸿蒙系统的厉害之处在于 你可能非用不可 !【手机吧】_百度贴吧...
  3. mysql数据库表空间最大值_mysql 数据库取最大值
  4. 星星评价控件android开发_android自定义星级评分控件,可实现只显示实心星星
  5. java中用iterator去检查最大值_Java中的Iterator vs forEach
  6. springboot 禁用 cookie / chrome 禁用 cookie
  7. 【mysql】table中添加列
  8. php 原生多图上传,php 原生多图文件上传
  9. DataWhale sklearn学习笔记(一)
  10. windows上安装mysql