angular中的表单数据自定义验证
之前说过了angular是如何给表单的数据进行基本的,常用的验证的:angular学习笔记(二十)-表单验证
但是在实际工作中,这些验证是远远不够的,很多时候我们需要自定义一些验证规则,以及一些异步,需要向后台发送请求的验证.
这篇文章就来讲解,如何自定义验证规则.
同时,这篇文章还是angular指令中使用ngModelController中关于 $validators 属性和 $asyncValidators 和 $pending 属性的详细讲解.
首先,需要自定义指令,设置require属性为'?^ngModel',在指令的link函数中通过第四个参数ctrl,获取到ngModelController这个东西.
ngModelController实例有两个对象,一个是 $validators对象,一个是 $asyncValidators对象.当我们需要添加自定义的同步验证规则时,使用$validators对象,当我们需要添加自定义的异步验证规则时,使用$asyncValidators对象.
通过栗子来说明:
html:
<!DOCTYPE html>
<html ng-app="customControl">
<head>
<title>asyncValidators</title>
<meta charset="utf-8">
<script src="angular-1.3.2.js"></script>
<script src="script.js"></script>
<link type="text/css" href="bootstrap.css" rel="stylesheet" />
<style>
*{font-family: 'MICROSOFT YAHEI'}
</style>
</head>
<body>
<div class="container" ng-controller="ctrl">
<div class="page-header">
<h1>ngModelController- <small>asyncValidators实现异步验证表单</small></h1>
</div>
<form role="form" name="myForm">
<div class="form-group">
<input validate-name type="text" name="myWidget" ng-model="userContent" ng-model-options="{updateOn:'blur'}" class="form-control" required>
</div>
<div class="alert alert-danger" role="alert" ng-show="myForm.myWidget.$error.required">
<strong>Oh!</strong> 必填!
</div>
<div class="alert alert-danger" role="alert" ng-show="myForm.myWidget.$error.validCharacters">
<strong>Oh!</strong> 不符合自定义的验证规则!
</div>
<div class="alert alert-danger" role="alert" ng-show="myForm.myWidget.$error.uniqueUsername">
<strong>Oh!</strong> 已经存在的用户名!
</div>
</form>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">用户名:</h3>
</div>
<div class="panel-body">
{{userContent}}
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">正在异步验证中:</h3>
</div>
<div class="panel-body">
{{myForm.myWidget.$pending}}
</div>
</div>
</div> </body>
</html>
这段html里,input元素使用了validate-name这个指令,后面在js中我们会通过这个指令来给它添加验证.注意元素必须要有ng-model属性,否则也没有什么意义了...
这个指令我们共验证三项,且在元素失去焦点的时候进行验证:
1.required : ng内置的的验证,需要在指令的最后添加required属性. 然后自己指令里什么也不用写,就可以验证它是否为空了.
2.validCharacters: 自定义的一个同步验证规则,验证输入的内容是否包含'bunny'字符串,自定义的验证不需要在指令最后添加validCharacters属性
3.uniqueUsername: 自定义的一个异步验证规则,验证输入的用户名是否已经被注册,同样,自定义的规则不需要在指令的最后添加uniqueUsername属性
然后来看js代码:
var app = angular.module('customControl',[]);
app.controller('ctrl',function($scope){
});
app.directive('validateName',function($http,$q){
return {
restrict:'A',
require:'?^ngModel',
link:function(scope,iele,iattr,ctrl){
ctrl.$validators.validCharacters = function(modelValue, viewValue) {
var value = modelValue || viewValue;
return value ? value.indexOf('bunny')!==-1 : true
};
ctrl.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
var value = modelValue || viewValue;
// Lookup user by username
return $http.get('/api/users/' + value).
then(function resolved(res) {
if(res.data){
//用户名已经存在,验证失败,给下一个promise传递失败通知.
return $q.reject('res.data');
}
else {
//用户名不存在,验证成功.
return true
}
}, function rejected() {
})
};
}
}
});
先说 validCharacters 验证: 我们给ctrl(也就是ngModelController的实例)的$validators属性添加了validCharacters属性,它的属性值为一个函数,函数接受两个参数modelValue和viewValue,这两个参数具体分别代表什么,请入angular指令中使用ngModelController查看,总之,这里可以认为就是input的value值.然后我们通过这个自定义的函数的返回值来确定是否通过验证,如果是true,则通过验证,如果是false,则不通过验证,在不通过验证的时候,$error.validCharacters就会为true.
同理,来看uniqueUsername 验证:我们给ctrl的$asyncValidators属性添加了uniqueUsername属性,它的属性值为一个函数,函数接受的参数也同上,然后我们通过$http发送请求来验证用户名是否存在:
node代码:
var express = require('express');
var app = express();
app.use(express.static(__dirname+''));
app.use(express.bodyParser());
app.use(express.methodOverride());
var names = [
'code_bunny','mi_bunny','hua_bunny'
];
app.get('/api/users/:name',function(req,res){
setTimeout(function(){
var name = req.params.name;
names.forEach(function(list){
if(name==list) {
res.send(list);
}
else {
res.end()
}
});
},1000);
});
app.listen(9000);
我们故意延迟了1000毫秒再给出响应,这样,在等待响应的时间里,我们可以看到myForm.myWidget.$pending发生的变化:

当得到响应后,它就会变为空.
所以,$pending属性里放置的是所以正在等待响应的异步验证.
最重要的一点,$asyncValidators的验证函数返回值比如是一个promise对象.根据这个promise对象发出的通知来决定验证是成功还是失败.如果发出的是失败通知,那么它就是验证失败,比如这里的$q.reject().如果发出的是成功通过,那么他就是验证成功,比如这里的return false.
这里要注意promise的用法:由于$http.get()返回的promise,无论执行的是resolved函数还是rejected函数,他发送给下一个promise的通知总是成功的,所以为了发送失败通知,必须使用$q.reject().
另外,我本来想尝试如果能搜索到用户名,则返回搜索到的用户名,如果不能,则不返回,让它接收到404状态,然后调用rejected函数,但是没能成功,因为如果不返回,它会请求很长一段时间才算请求失败,而不是一旦发现找不到就立刻算请求失败了.所以这里还是根据搜索结果返回不同值来进行判断.
完整代码: https://github.com/OOP-Code-Bunny/angular/tree/master/ngModelController/asyncValidators
angular中的表单数据自定义验证的更多相关文章
- angular中的表单验证
angular中的表单验证很强大, 一共有5中验证信息,$valid,$invalid,$pristine,$dirty,$error. $valid-----当验证通过的时候,为true,不通过的时 ...
- Vue学习之--------Vue中收集表单数据(使用v-model 实现双向数据绑定、代码实现)(2022/7/18)
文章目录 1.Vue中实现表单数据的收集 1.1 基础知识 1.2 代码实例 1.3 测试效果 1.4 额外插一嘴 1.Vue中实现表单数据的收集 1.1 基础知识 表单中常用的标签:input(输入 ...
- strus2中获取表单数据 两种方式 属性驱动 和模型驱动
strus2中获取表单数据 两种方式 属性驱动 和模型驱动 属性驱动 /** * 当前请求的action在栈顶,ss是栈顶的元素,所以可以利用setValue方法赋值 * 如果一个属性在对象栈,在页面 ...
- layer.open弹框中的表单数据无法获取
layer.open弹框中的表单数据无法获取 表单数据模板 layer.open() 页面效果: 当点击确定后,radio和textarea获取的值总是为空,解决办法: var setPriCustB ...
- gin中绑定表单数据至自定义结构体
package main import "github.com/gin-gonic/gin" type StructA struct { FieldA string `form:& ...
- Angular11 模板表单、响应式表单(自定义验证器)、HTTP、表单元素双向绑定
1 模板表单 模型通过指令隐式创建 技巧01:需要在模块级别引入 FormsModule ,通常在共享模块中引入再导出,然后在需要用到 FormsModule 的模块中导入共享模块就可以啦 impor ...
- Action 中获取表单数据的三种方式
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/53138905 冷血之心的博客) Action 中获取表单提交数据 ...
- iview表单密码自定义验证
From中定义 ref="passwordForm" 获取dom节点 :model="passwordForm" 关联表单数据对象 :rules=&quo ...
- easyui 表单和自定义验证扩展和js自定义返回值
================jsp==========================<form method="post" id="regfrminp&qu ...
随机推荐
- 读书笔记--<精益和敏捷开发大型项目应用指南>
[摘要] 3月份的时候,根据教练和其他多为项目经理的推荐,开始阅读这本书:本书共三大部分.12个章节,第一部分:思考工具,第二部分:组织工具:第三部分:杂记:全书相当于对精益思想和敏捷团队组织.Scr ...
- web-app_2_5.xsd内容
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://w ...
- [转载]在VirtualBox中收缩虚拟磁盘映像文件
原文地址:在VirtualBox中收缩虚拟磁盘映像文件作者:bobby 由于经常要测试一些软件,我在VirtualBox虚拟机中安装了一套Windows.使用过虚拟机的朋友都知道,为了节省硬盘空间,一 ...
- 神秘的40毫秒延迟与 TCP_NODELAY
写 HTTP Server,不可免俗地一定要用 ab 跑一下性能,结果一跑不打紧,出现了一个困扰了我好几天的问题:神秘的 40ms 延迟. Table of Contents 1 现象 2 背后的原因 ...
- 进阶之路(基础篇) - 009 通过底层AVR方法实现SPI数据传输
主机端: /********************************* 代码功能:通过底层AVR方法实现SPI数据传输(主机端) 创作时间:2016*10*17 使用资源: 更低阶的 aTme ...
- windbg(1)
1.http://www.cnblogs.com/huangyong9527/category/384128.html 2.http://www.cnblogs.com/pugang/category ...
- Spring Boot中MyBatis的使用
orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开 ...
- mysql数据库优化 pt-query-digest使用
mysql数据库优化 pt-query-digest使用 一.pt-query-digest工具简介 pt-query-digest是用于分析 mysql慢查询的一个工具,它可以分析binlog.Ge ...
- 使用Nexus搭建Maven内部服务器
概述 我们在使用maven时,一般通过网络上一些公共的maven仓库来获取jar包,但是有时候会碰到网速比较慢的情况就比较郁闷,Nexus是一个maven的服务器,可以让我们搭建一个本 ...
- C# Log4net根据日志等级输出到不同文件
原文地址: Log4Net.Config <?xml version="1.0" encoding="utf-8"?> <configurat ...