15

我创建了一个自定义验证器,要求日期是过去的。在字段中手动输入日期时,验证似乎效果很好。但是,如果我以编程方式输入更改日期(直接更改模型而不是在字段中键入),则不会触发验证。

我相信我正在按照文档中的指示执行自定义验证指令。 这是一个说明问题的jsFiddle。在小提琴中,如果您单击“以编程方式更改日期”按钮,您会看到验证错误不会显示(但如果您手动更改它会显示)。这是指令代码(也在小提琴中):

myApp.directive('pastDate', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, ctrl) {
            ctrl.$parsers.unshift(function (viewValue) {
                var today = new Date();
                today = new Date(today.getFullYear(), today.getMonth(), today.getDate());

                if (new Date(viewValue) < today) {
                    ctrl.$setValidity('pastDate', true);
                    return viewValue;
                }
                ctrl.$setValidity('pastDate', false);
                return undefined;
            });
        }
    };
});
4

2 回答 2

19

模型绑定有两种方式,$parsers控制视图到模型方向$formatters的管道,控制模型到视图方向的管道。当您更新控制器中的模型时,更改会通过$formatters管道。

我已将您的代码更新为:this,因此它可以处理两种方式。

myApp.directive('pastDate', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, ctrl) {
            function validate (value) {
                var today = new Date();
                today = new Date(today.getFullYear(), today.getMonth(), today.getDate());

                if (new Date(value) < today) {
                    ctrl.$setValidity('pastDate', true);
                    return value;
                }
                ctrl.$setValidity('pastDate', false);
                return value;
            }
            ctrl.$parsers.unshift(validate);
            ctrl.$formatters.unshift(validate)
        }
    };
});
于 2013-07-12T19:37:03.590 回答
11

自 Angular 1.3 提供$validators属性以来的新答案。

从 1.3 开始,$parsers$formatters应该再设置有效性,即使它仍然可能。

然后你的代码变得更简单:

myApp.directive('pastDate', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, ctrl) {
            ctrl.$validators.pastDate = function(modelValue) { // 'pastDate' is the name of your custom validator ...
                var today = new Date();
                today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
                return (new Date(modelValue) < today);
            }
        }
    };
});

更新了 jsFiddle:http: //jsfiddle.net/jD929/53/

于 2014-10-28T14:58:53.537 回答