不是我不喜欢或不喜欢,但问题是同步验证器的行为有所不同。即使其他验证器之前失败,也始终会调用它们。因此,验证器中存在不均匀的行为,这也会导致一些问题。
我用一个简单的程序测试了所有这些。
我创建了一个同步验证器和一个验证完全相同的异步验证器。 在两个验证器中,我以“典型”方式提交错误:
ctrl.$validators.sync= function(modelValue,viewValue){...
我还提交了一个额外的错误(例如告诉异步验证中存在连接问题):
ctrl.$setValidity('syncplus',...
此外,除了不均匀的行为之外,额外的验证错误还会导致异步验证器中的其他问题:
正如我所看到的,如果输入被修改,异步“典型”验证总是立即重置。 (我不知道在哪里) 但是额外的验证器永远不会重置。并且,由于当其他验证器失败时未调用异步验证器,我无法更新其他验证器,因此仍然会显示之前的错误,即使它可以是有效输入。
在这里你可以看到验证器的js代码:
angular.module('app',[])
.directive('async', function($q,$timeout){
return{
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl){
var nono_username= ['a','aa','aaa','aaaaa']; // SHOULD FAIL from 1 to 5 a's, BUT NOT with 4 a's
ctrl.$asyncValidators.async= function(modelValue,viewValue){
scope.data.called+= 'A'; // This way we know Async has been called
var def= $q.defer();
$timeout(function() { // Mock a delayed response
if(nono_username.indexOf(modelValue)===-1){ // The username is available
ctrl.$setValidity('asyncplus',true);
def.resolve();
} else {
ctrl.$setValidity('asyncplus',false);
def.reject();
}
}, 200);
return def.promise;
};
}
};
})
.directive('sync', function($q){
return{
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl){
var nono_username= ['a','aa','aaa','aaaaa']; // SHOULD FAIL from 1 to 5 a's, BUT NOT with 4 a's
ctrl.$validators.sync= function(modelValue,viewValue){
scope.data.called+= 'S'; // This way we know Sync has been called
ctrl.$setValidity('syncplus',nono_username.indexOf(modelValue)===-1);
return nono_username.indexOf(modelValue)===-1;
};
}
};
})
/* Maybe a solution for resetting asyncplus?
.directive('asyncplus', function($q){
return{
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl){
ctrl.$validators.asyncplus= function(modelValue,viewValue){
return true;
};
}
};
})
*/
.controller('Controller',['$scope',function($scope){
$scope.data= {username:'',called:''};
}]);
结论:
答案 0 :(得分:0)
如果你想让它像这样工作,你可以使用$ parsers和$ formatters:
.directive('async', function($q,$timeout){
return{
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl){
var nono_username= ['a','aa','aaa','aaaaa']; // SHOULD FAIL from 1 to 5 a's, BUT NOT with 4 a's
var validate = function(value) {
$timeout(function() { // Mock a delayed response
if(nono_username.indexOf(value)===-1){ // The username is available
ctrl.$setValidity('asyncplus',true);
} else {
ctrl.$setValidity('asyncplus',false);
}
}, 200);
return value;
};
ctrl.$parsers.push(validate);
ctrl.$formatters.push(validate);
}
};
})