1

我写了两个验证指令。每个都可以单独工作,但是当两者都应用时,numberValidator 会在 rangeValidator 失败时失败(因此,因为“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;
                }
            });
        }
    };
});
4

1 回答 1

2

我看到你已经遵循了 Angular 文档的建议,并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;
});

工作演示在这里

这不会阻止使用无效值更新模型,并且您需要使用$validor$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>

工作演示在这里

它带有一个警告:随着更多验证的添加,它可能会变得非常混乱。

我个人更喜欢第一种方法,即使它不会阻止模型使用无效值进行更新。

于 2013-10-19T06:51:54.470 回答