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 ...
随机推荐
- 转:Ogre内部渲染流程
以下是 Ogre 的代码中的详细说明: Renderable是OGRE中所有可渲染对象的抽象接口 这个接口抽象出了在渲染管线中的被分组的离散的可渲染对象基本的方法. 此接口的实现类必须是基于单一的材质 ...
- 通过Parcelable协议传递数据出现系列错误
07-14 00:42:37.414: E/AndroidRuntime(17687): FATAL EXCEPTION: main 07-14 00:42:37.414: E/AndroidRunt ...
- JavaScript判断是否全为中文,是否含有中文
来源于:http://blog.csdn.net/yenange/article/details/7463897 第一种代码(全为中文则返回"true",不全为中文则返回" ...
- 一个使用Servlet文件实现文件下载的实例
一个使用Servlet文件实现文件下载的实例 (可以扩充本实例实现:对用户隐藏他要下载文件的路径,或者在下载文件时要做一些其他的工作,如检查用户有没有下载此文件的权限等) 了解在Servlet中如何控 ...
- maven 下载 源码和javadoc命令(转)
转自:http://blog.csdn.net/topwqp/article/details/8902863 maven 下载 源码和javadoc命令 目录(?)[+] Maven命令下载源码和ja ...
- C链表的简单案例
此案例只是简单的使用链表 链表的特点: 1.不需要提前知道要存入数据的长度 2.最后结点为NULL 3.头结点指向下一个结点的结构体指针 #include <stdio.h> #inclu ...
- 【Oracle】详解Oracle中NLS_LANG变量的使用
目录结构: contents structure [+] 关于NLS_LANG参数 NSL_LANG常用的值 在MS-DOS模式和Batch模式中设置NLS_LANG 注册表中NLS_LANG和系统环 ...
- Oracle 12C -- plug unplugged PDB into CDB
connetct to CDB as a common user and verify that pdb_test is closed SQL> select con_id,dbid,name, ...
- CListCtrl设置选中行
原文链接: http://blog.163.com/lejianz@126/blog/static/11650292013610103232600/ CListCtrl 设置选中状态 1. 使用CLi ...
- Qt Creator中如何添加C++0x支持
最近在学习多线程编程,本人平时习惯使用Qt Creator写程序,只是作为C++编辑器,很少使用Qt library中的类. Multi Threading作为C++11标准已经纳入C++标准库了,可 ...