我有以下验证器指令:
directive('myValidate', function($timeout) {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
if(!scope.requirementSpec){
scope.requirementSpec = {};
}
if(Boolean(attrs.valueRequired) || Boolean(attrs.minLength) && elm[0].value != ""){
console.log(scope.model[attrs.name]);
ctrl.$setValidity(attrs.name, false);
// elm.removeClass('ng-valid').addClass('ng-invalid');
}
elm.on('focus', function(){
console.log(elm);
console.log(ctrl);
var form = elm.parents().find('form');
// $timeout(function(){$ctrl.$dirty = true;}, 0);
});
ctrl.$parsers[0] = (function(viewValue) {
scope.valid = true;
scope.fieldName = attrs.name;
var nameStr = attrs.name + '';
var nameObj = nameStr.split('_');
for(var i = 0; i < nameObj.length; ++i){
nameObj[i] = nameObj[i].substr(0, 1).toUpperCase() + nameObj[i].slice(1);
}
var nameStrParsed = nameObj.join(' ');
scope.fieldErrorDisplay = Boolean(nameStrParsed) ? nameStrParsed : 'This field';
if(attrs.valueRequired && viewValue.length == 0 && !attrs.minLength){
scope.valid = false;
scope.requirementSpec[nameStr] = [{
'msg' : scope.fieldErrorDisplay + ' is required',
'class' : undefined
}];
}
else{
// scope.fieldErrorDisplayObj[nameStr] = scope.fieldErrorDisplay + ' must meet the following requirements: ';
scope.requirementSpec[nameStr] = [];
if(attrs.minLength){
var itemValidity = viewValue.length >= attrs.minLength;
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'At Least ' + attrs.minLength + ' Chars',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpecrequirementSpec[nameStr].push(item);
}
else if(attrs.valueRequired){
var itemValidity = viewValue && viewValue.length >= 1;
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'This field must be filled',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
if(attrs.maxLength){
var itemValidity = viewValue.length <= attrs.maxLength;
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : attrs.maxLength + ' Chars At Most ',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
if(attrs.minLetters){
var itemValidity = (viewValue && /[A-z]/.test(viewValue));
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'Must contain at least ' + attrs.minLetters + ' letters',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
if(attrs.minNumbers){focus
var itemValidity = (viewValue && /\d/.test(viewValue));
scope.valid = !itemValidity ? false : scope.valid;
var item = {
'msg' : 'Must contain at least' + attrs.minNumbers + ' numbers',
'class' : itemValidity ? 'valid' : undefined
};
scope.requirementSpec[nameStr].push(item);
}
}
if(scope.valid) {
var errorsPresent = false;
for(var i = 0; i < scope.requirementSpec[nameStr].length; i++){
if(!scope.requirementSpec[nameStr][i].class){
errorsPresent = true;
}
}
scope.requirementSpec[nameStr] = errorsPresent ? scope.requirementSpec[nameStr] : [];
ctrl.$setValidity(nameStr, true);
elm.removeClass('ng-required-invalid').removeClass('validatorError').removeClass('ng-invalid').addClass('ng-valid');
return viewValue;
} else {
ctrl.$setValidity(nameStr, false);
return undefined;
}
});
}
};
}).
如您所见,在链接函数中,我检查了我应用此指令的输入元素的值是否为空,并将此元素的有效性设置为 false。
当我使用此指令验证编辑表单时,问题就出现了,其中值是通过对 REST 资源的 XHR 请求检索的。
我的问题是:我该如何处理这个问题,并将这个逻辑绑定到该字段的 ng-model 上,而不是 $watching 每个单独的,这将是一种可怕的浪费。
也许我可以让 $parser 对字段模型的变化做出反应,而不仅仅是直接用户输入?