我有以下验证指令:
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;
}
});
}
};
}).
正如您所看到的,在link函数中,我检查我在其上应用此指令的input元素的值是否为空,并将此元素设置为valid为false。
当我使用此指令验证编辑表单时会出现问题,在该表单中,值将通过对REST资源的XHR请求进行检索。
我的问题是:如何处理这个问题,并将这个逻辑绑定到字段的ng-model上,而不是单独观看每个字段,这将是一个可怕的浪费。
也许我可以让$解析器对字段模型的变化做出反应,而不仅仅是直接用户输入?。
答案 0 :(得分:1)
如果我理解正确,您正在尝试侦听对ngModel / Form元素所做的更改?
尝试在你的ngModel上添加一个$ watch监听器,如下所示:
scope.$watch(attrs.ngModel, function(val) {
// React the the value changes
})
答案 1 :(得分:0)
答案在Angularjs文档中提供了表单: http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController# $格式化
$ formatters是模型与指令评估的值之间的管道。
请关闭。