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 ...
随机推荐
- Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境
使用Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境(一) 2015-01-14 20:28 by 飘扬的红领巾, 4322 阅读, 5 评论, 收藏, 编辑 ...
- Electromagnetic radiation and Radio 电磁波/电磁辐射和无线电波
电磁辐射,又称电磁波,是由同相振荡且互相垂直的电场与磁场在空间中以波的形式传递能量和动量,其传播方向垂直于电场与磁场构成的平面. 电磁辐射的载体为光子,不需要依靠介质传播,在真空中的传播速度为光速.电 ...
- 创业成本?亲身经历告诉你做一个app要多少钱
导语:作为一名苦逼的移动互联网创业者,被外行的朋友们问及最多的问题是“做一个网站需要多少钱?”或者“做一个APP需要多少钱?” 作为一名苦逼的移动互联网创业者,被外行的朋友们问及最多的问题是“做一个网 ...
- shell 脚本启动tomcat服务
#!/bin/bash # kill tomcat进程 tomcat_fashion_dev_pid=`ps aux|grep tomcat_fashion_dev|grep -v "gre ...
- Apache+PHP配置PATHINFO的一个小问题
使用ThinkPHP示例,设置'URL_MODEL' => 2,发现提示: No input file specified 应该是PATHINFO配置的问题,试 ...
- linux shell 脚本攻略学习2
1.关于文件描述符和重定向: 文件描述符是与一个打开的文件或数据流相关联的整数.文件描述符0.1以及2是系统预留的. 0——stdin(标准输入) 1——stdout(标准输出) 2——stderr( ...
- ipsec协议(转)
from:http://lulu1101.blog.51cto.com/4455468/816875 ipsec协议 2012-03-25 23:40:28 标签:休闲 ipsec协议 职场 IPSe ...
- Ubuntu中恢复rm命令误删文件(转)
计算机系统:Ubuntu 16.04 1 背景 在做项目的时候,本来想使用rm命令删除以14开头的文件,结果写成如下形式: rm 14 * 注意,本来14和*之间不应该有空格的,但是误写了一个空格,结 ...
- ASP.NET Core 不同操作系统环境安装之Hello World 教程
Official Website:https://www.microsoft.com/net/learn/get-started-with-dotnet-tutorial#install Window ...
- 自己写的一个Solr搜索实例,增删改查+高亮+分页
今天个人coding的模块测试,所以闲暇之余继续研究solr,然后顺带写了一个实例,随便搞的,solr真心不熟,期待认识热爱搜索的朋友,共同进步. 1.配置schema.xml文件[solr\coll ...