这里只以表单里面的“输入密码”和“确认密码”为例,来看一下再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

随机文章

火狐安装包下载
火狐安装包下载

evernote(印象笔记)开始测试手写功能了
evernote(印象笔记)开始测试手写功能了

设置java环境变量
设置java环境变量

谷歌生日,9月27日?
谷歌生日,9月27日?

QQ漂流瓶更好玩了,装有GPS导航
QQ漂流瓶更好玩了,装有GPS导航

相关文章

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

让网站快速提醒用户升级IE6,letskillie6
让网站快速提醒用户升级IE6,letskillie6

AngularJS的controllerAs常见用法
AngularJS的controllerAs常见用法

新的英伟达芯片能让手机拥有电脑版的性能
新的英伟达芯片能让手机拥有电脑版的性能

将自己学得java源代码公布
将自己学得java源代码公布

如果android能运行windows程序,你会不会更喜欢android
如果android能运行windows程序,你会不会更喜欢android

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