我写了两个验证指令。每个都可以单独工作,但是当两者都应用时,numberValidator会在任何时候失败.Validator失败(因此,因为“3”无法执行rangeValidator,它也会失败numberValidator,即使它在rangeValidator不在图片中时也会失败)。
日志记录验证numberValidator确实失败了(与HTML中的某些错误相比)。
我原本希望这些指令能够彼此独立运行 - 我不希望用户输入“3”并仍然看到“必须是一个数字。”
使用数字输入不是一种选择。
我的JS:
app.directive('rangeValidator', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
var min = scope.$eval(attrs.minValue);
var max = scope.$eval(attrs.maxValue);
ctrl.$parsers.unshift(function (viewValue) {
if (parseInt(viewValue) >= min && parseInt(viewValue) <= max) {
// it is valid
ctrl.$setValidity('rangeValidator', true);
return viewValue;
} else {
// it is invalid, return undefined (no model update)
ctrl.$setValidity('rangeValidator', false);
return undefined;
}
});
}
};
});
app.directive('numberValidator', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue) {
if (!isNaN(parseInt(viewValue))) {
// it is valid
console.log('Number Validator passed!');
ctrl.$setValidity('numberValidator', true);
return viewValue;
} else {
// it is invalid, return undefined (no model update)
ctrl.$setValidity('numberValidator', false);
return undefined;
}
});
}
};
});
答案 0 :(得分:2)
我看到你已经遵循了Angular docs的建议,并在解析器函数中返回了undefined
的无效值。这样做(在你的情况下)的问题是它破坏了解析器管道:首先检测到无效值的指令会将undefined
传递给下一个,这显然也会认为它无效。
我可以想到两个解决方案:
1)让原始值流过解析器管道:
ctrl.$parsers.unshift(function (viewValue) {
if (parseInt(viewValue) >= min && parseInt(viewValue) <= max) {
ctrl.$setValidity('rangeValidator', true);
} else {
ctrl.$setValidity('rangeValidator', false);
}
return viewValue;
});
...
ctrl.$parsers.unshift(function (viewValue) {
if (!isNaN(parseInt(viewValue))) {
ctrl.$setValidity('numberValidator', true);
} else {
ctrl.$setValidity('numberValidator', false);
}
return viewValue;
});
工作演示here。
这不会阻止使用无效值更新模型,并且您需要使用$valid
或$invalid
属性在使用其值之前检查字段状态,但是您'能够彼此独立地检查错误。
2)为两个指令设置不同的优先级
您可以通过为每个指令设置不同的优先级来控制指令的执行顺序,通过这样做,您可以以增量方式检查无效值,如下所示:
<span ng-show="form.value.$error.rangeValidator">Invalid range</span>
<span ng-show="!form.value.$error.rangeValidator && form.value.$error.numberValidator">Invalid number</span>
工作演示here。
它附带一个警告:随着更多验证的增加,它可能会变得非常混乱。
就个人而言,我更喜欢第一种方法,即使它不会阻止模型使用无效值进行更新。