这里只以表单里面的“输入密码”和“确认密码”为例,来看一下再angular1.3之前用的$parsers和1.3之后新增的$validators数组实现验证的方法区别。
先来看看HTML代码部分

<!-- 密码型字段 -->
	<div>
		<label for="_password">密码</label>
		<input type="password" id="_password" name="password" ng-model="vm.form.password" ng-required="true">
	</div>
	<div>
		<label for="_retypedPassword">确认密码</label>
		<input type="password" id="_retypedPassword" ng-model="vm.retypedPassword" bf-field-error bf-assert-same-as="vm.form.password">
	</div>

里面的bf-field-error指令是用来显示错误消息的,而bf-assert-same-as是特地为“确认密码”新增的指令,用来提示“两次的输入密码不符”的错误提示。
下面是指令bf-field-error的代码

.directive('bfFieldError', function($compile){
	return {
		restrict: 'A',
		require: 'ngModel',
		link: function(scope, ele, att, ngModelCtrl){
			//创建一个独立作用于的子scope
			var subScope = scope.$new(true);
			subScope.hasError = function(){
				//除了判断是否无效外,还要判断是否已经输入过
				return ngModelCtrl.$invalid && ngModelCtrl.$dirty;
			};
			subScope.errors = function(){
				//先直接显示到界面上,回头再改进为用户友好的方式
				return ngModelCtrl.$error;
			};
			//把一段HTML编译成"活dom",然后把subScope传递给它,这个"活dom"将会跟随subScope的变化自动更新自己
			var hint = $compile('<ul class="bf-field-error" ng-if="hasError()"><li ng-repeat="(name, wrong) in errors()" ng-if="wrong">{{name | errors}}</li></ul>')(subScope);
			//把这段"活dom"追加到当前元素后面,好让它显示出来
			ele.after(hint);
		}
	};
})

接着是我们的主角bf-assert-same-as

.directive('bfAssertSameAs', function(){
	return {
		restrict: 'A',
		require: 'ngModel',
		link: function(scope, ele, att, ngModelCtrl){
			var isSame = function(value){
				//取对照值,通过scope.$eval把att.bfAssertSameAs作为一个表达式在当前作用域中求值,否则它只是一个固定的字符串
				var anotherValue = scope.$eval(att.bfAssertSameAs);
				return value === anotherValue;
			};
			
			 //1.2.x只能用$parsers实现验证
			 ngModelCtrl.$parsers.push(function(value){
			 	//调用$setValidity设置验证结果,第一个参数是名字,和$error中的属性名一致,但是取值相反,因为这里表示的是“有效”,而$error中表示“无效”
			 	ngModelCtrl.$setValidity('same', isSame(value));
			 	return true;
			 });
			 // 这是assertSameAs验证器所特有的,因为当对照值(即vm.form.password)发生变化时,也要更新有效性状态
			 scope.$watch(function(){
			 	return scope.$eval(att.bfAssertSameAs);
			 }, function(){
			 	//变化时重新判断并设置验证结果
			 	ngModelCtrl.$setValidity('same', isSame(ele.val()));
			});
		}
	};
})

需要注意的是$setValidity的返回值为 undefined或者false时会在 $error里面会存在parse:true的问题,上面选择了直接返回true
如果用最新的$validators数组则应该这样写,他需要返回布尔类型的值

.directive('bfAssertSameAs', function(){
	return {
		restrict: 'A',
		require: 'ngModel',
		link: function(scope, ele, att, ngModelCtrl){
			var isSame = function(value){
				//取对照值,通过scope.$eval把att.bfAssertSameAs作为一个表达式在当前作用域中求值,否则它只是一个固定的字符串
				var anotherValue = scope.$eval(att.bfAssertSameAs);
				return value === anotherValue;
			};
                        //1.3.x增加了专门的$validators数组,可用更好的方式实现验证。这里个数组都是放需要被执行的函数的                        
			ngModelCtrl.$validators.same = function(value){ //返回值必须是boolean类型
				//调用$setValidity设置验证结果,第一个参数是名字,和$error中的属性名一致,但是取值相反,因为这里表示的是“有效”,而$error中表示“无效”
				return isSame(value);
			};
			// 这是assertSameAs验证器所特有的,因为当对照值(即vm.form.password)发生变化时,也要更新有效性状态
			scope.$watch(function(){
				return scope.$eval(att.bfAssertSameAs);
			}, function(newValue){
				
				//变化时重新判断并设置验证结果
				ngModelCtrl.$setValidity('same', isSame(ele.val()));
			});
		}
	};
})

效果如下:baidushurufa_2016-10-21_18-25-20

随机文章

android手机QQ2012很给力
android手机QQ2012很给力

Spill将其“同情引擎”扩展至高中生和研究生
Spill将其“同情引擎”扩展至高中生和研究生

分享jquery仿apple官网伸缩弹性搜索框
分享jquery仿apple官网伸缩弹性搜索框

辛亥革命电影(国语+字幕)下载
辛亥革命电影(国语+字幕)下载

新浪sae服务器故障,svn无法正常工作
新浪sae服务器故障,svn无法正常工作

百度开放云BAE下周四扩容
百度开放云BAE下周四扩容

相关文章

angularjs2会报错“GET http://127.0.0.1/traceur 404 (Not Found)”
angularjs2会报错“GET http://127.0.0.1/traceur 404 (Not Found)”

新浪发的公告延时严重
新浪发的公告延时严重

U盘安装ubuntu linux, 重启后屏幕一直停留在Peter Anvin et al
U盘安装ubuntu linux, 重启后屏幕一直停留在Peter Anvin et al

第二十一讲:网络编程(一)
第二十一讲:网络编程(一)

终于实现win主机wordpress评论回复发送邮件通知
终于实现win主机wordpress评论回复发送邮件通知

内容分享:道招
本文链接:angular表单验证$parsers和$validators方式区别
道招声明:除特别标注或作者不详外,本站所有文章均为原创,转载请注明。欢迎共同关注互联网!