如何在 angular 中的输入字段上附加验证器以访问表单中的另一个模型

How do I attach validators on an input field in angular that accesses another model in the form

我在表单上有一个范围输入(介于 [lowerValue] 和 [upperValue] 之间),我想制作一个名为 'validateGreaterThan' 的可重用指令,它可以附加到任何表单并使用 ngModel $validators功能,以便我可以将多个附加到一个输入上。

您可以在此处查看 jsbin 上的简单演示:

http://jsbin.com/vidaqusaco/1/

我已经设置了一个名为 nonNegativeInteger 的指令并且可以正常工作,但是,我的 validateGreaterThan 指令不起作用。我怎样才能让它引用 lowerValue?

感谢您对此提供的任何帮助。

基本思路如下:-

定义 2 个指令,让每个指令引用 other 字段 buy 并传递其名称。当验证器在当前字段上运行时,您可以检索另一个字段的模型值,现在您拥有两个字段的值,并且可以确保这两个字段之间的关系。

根据我下面的代码,我有 2 个字段 minimumAmountmaximumAmount,其中最小金额不能大于最大金额,反之亦然。

<input name="minimumAmount"  type="number" class="form-control" 
             ng-model="entity.minimumAmount"
             less-than-other-field="maximumAmount" required/>

<input name="maximumAmount" type="number" 
              ng-model="entity.maximumAmount"
              greater-than-other-field="minimumAmount"
              class="form-control"/>

这里我们有 2 个指令 lessThanOtherFieldgreaterThanOtherField,当我们传递其他字段名称时,它们都引用其他字段。 greater-than-other-field="minimumAmount" 我们正在通过另一个字段。

 .directive('lessThanOtherField',  ['$timeout',function($timeout){
        return {
            require: 'ngModel',
            link: function (scope, elm, attrs, ctrl) {
                var xFieldValidatorName = 'lessThanOtherField';
                var form = elm.parent().controller('form');
                var otherFieldName = attrs[xFieldValidatorName];
                var formFieldWatcher = scope.$watch(function(){
                    return form[otherFieldName];
                }, function(){
                    formFieldWatcher();//destroy watcher
                    var otherFormField = form[otherFieldName];
                    var validatorFn = function (modelValue, viewValue) {
                        var otherFieldValue = otherFormField.hasOwnProperty('$viewValue') ? otherFormField.$viewValue : undefined;
                        if (angular.isUndefined(otherFieldValue)||otherFieldValue==="") {
                            return true;
                        }
                        if (+viewValue < +otherFieldValue) {
                            if (!otherFormField.$valid) {//trigger validity of other field
                                $timeout(function(){
                                    otherFormField.$validate();
                                },100);//avoid infinite loop
                            }
                            return true;
                        } else {
                            // it is invalid, return undefined (no model update)
                            //ctrl.$setValidity('lessThanOtherField', false);
                            return false;
                        }
                    };

                    ctrl.$validators[xFieldValidatorName] = validatorFn;
                });
            }
        };

    }])
    .directive('greaterThanOtherField', ['$timeout',function($timeout){
        return {
            require: 'ngModel',
            link: function (scope, elm, attrs, ctrl) {
                var xFieldValidatorName = 'greaterThanOtherField';
                var form = elm.parent().controller('form');
                var otherFieldName = attrs[xFieldValidatorName];
                var formFieldWatcher = scope.$watch(function(){
                    return form[otherFieldName];
                }, function(){
                    formFieldWatcher();//destroy watcher
                    var otherFormField = form[otherFieldName];
                    var validatorFn = function (modelValue, viewValue) {
                        var otherFieldValue = otherFormField.hasOwnProperty('$viewValue') ? otherFormField.$viewValue : undefined;
                        if (angular.isUndefined(otherFieldValue)||otherFieldValue==="") {
                            return true;
                        }
                        if (+viewValue > +otherFieldValue) {

                            if (!otherFormField.$valid) {//trigger validity of other field
                                $timeout(function(){
                                    otherFormField.$validate();
                                },100);//avoid infinite loop
                            }
                            return true;
                        } else {
                            // it is invalid, return undefined (no model update)
                            //ctrl.$setValidity('lessThanOtherField', false);
                            return false;
                        }
                    };

                    ctrl.$validators[xFieldValidatorName] = validatorFn;
                });
            }
        };

    }])