angular表单验证$parsers和$validators方式区别
如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!
angular表单验证$parsers和$validators方式区别
<!-- 密码型字段 -->
<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()));
});
}
};
})
效果如下:
- 分类:
- Web前端
更新时间: