如果多个元素使用相同的自定义验证指令,如何验证表单

How to validate a form if multiple elements uses the same custom validation directive?

本文关键字:验证 指令 何验证 表单 自定义 元素 如果      更新时间:2023-09-26

我已经为这种格式的日期写了一个验证指令MM/YYYY,如果我每页只有一个元素要验证,那么它工作得很好,但是当我有多个元素时,我注意到验证是混合的,所以可能是scope误解。

我的意思是我得到minDateform.startDate元素的验证错误,而不是只看到form.endDate

这是我的观点:

<form>
    <input id="start-date"
           type="text"
           validate-short-date
           data-max-date="{{endingDate | toDate:'MM/YYYY':'YYYYMM'}}"
           data-greater-date="{{nextMonth | toDate:'MM/YYYY':'YYYYMM'}}"
           name="startDate"
           data-ng-model="startingDate">
    <input id="end-date"
           type="text"
           validate-short-date
           data-min-date="{{thisMonth | toDate:'MM/YYYY':'YYYYMM'}}"
           name="endDate"
           data-ng-model="endingDate">
</form>

我想使用scope[ngModel.$name],但问题只是部分修复,所以我可能错过了我应该如何使用范围来保持指令划分。

这是指令:

.directive('validateShortDate', ['moment', function(moment) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
            var pattern, regex;
            pattern = '^((0[0-9])|(1[0-2])|[1-9])'/(19|20)[0-9]{2}$';
            regex = new RegExp(pattern, 'i');
            var isEmpty = function(modelValue){
                return modelValue === '' || modelValue === null || angular.isUndefined(modelValue);
            };
            var toDate = function(modelValue){
                return moment(modelValue, 'MM/YYYY').format('YYYYMM');
            };
            scope[ngModel.$name] = {};
            scope[ngModel.$name].maxDate = false;
            scope[ngModel.$name].minDate = false;
            scope[ngModel.$name].greaterDate = false;
            scope[ngModel.$name].lesserDate = false;
            attr.$observe('maxDate', function() {
                if (!isEmpty(attr.maxDate)) {
                    scope[ngModel.$name].maxDate = attr.maxDate;
                    ngModel.$validate();
                }
            });
            attr.$observe('greaterDate', function() {
                if (!isEmpty(attr.greaterDate)) {
                    scope[ngModel.$name].greaterDate = attr.greaterDate;
                    ngModel.$validate();
                }
            });
            attr.$observe('minDate', function() {
                if (!isEmpty(attr.minDate)) {
                    scope[ngModel.$name].minDate = attr.minDate;
                    ngModel.$validate();
                }
            });
            attr.$observe('lesserDate', function() {
                if (!isEmpty(attr.lesserDate)) {
                    scope[ngModel.$name].lesserDate = attr.lesserDate   ;
                    ngModel.$validate();
                }
            });
            ngModel.$validators.maxDate = function(modelValue) {
                console.log(ngModel.$name);
                var maxDate = scope[ngModel.$name].maxDate;
                if (!isEmpty(modelValue) && !isEmpty(maxDate) && regex.test(modelValue)) {
                    return toDate(modelValue) <= maxDate;
                }
                return true;
            };
            ngModel.$validators.greaterDate = function(modelValue) {
                var greaterDate = scope[ngModel.$name].greaterDate;
                if (!isEmpty(modelValue) && !isEmpty(greaterDate) && regex.test(modelValue)) {
                    return toDate(modelValue) < greaterDate;
                }
                return true;
            };
            ngModel.$validators.minDate = function(modelValue) {
                var minDate = scope[ngModel.$name].minDate || false;
                if (!isEmpty(modelValue) && !isEmpty(minDate) && regex.test(modelValue)) {
                    return toDate(modelValue) >= minDate;
                }
                return true;
            };
            ngModel.$validators.lesserDate = function(modelValue) {
                var lesserDate = scope[ngModel.$name].lesserDate;
                if (!isEmpty(modelValue) && !isEmpty(lesserDate) && regex.test(modelValue)) {
                    return toDate(modelValue) > lesserDate;
                }
                return true;
            };
            ngModel.$validators.valid = function(modelValue) {
                return isEmpty(modelValue) || regex.test(modelValue);
            };
        }
    };
}])

我如何在同一视图中保持更多的验证指令?

您的怀疑是正确的,这是一个范围问题。您希望在这些指令上有一个隔离的作用域。看看这篇关于这个话题的博客文章。关于您的代码,请尝试以下更改…

.directive('validateShortDate', ['moment', function(moment) {
    return {
        restrict: 'A',
        scope: {}, // -- isolate - not shared with parent scope
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
        [...]

此外,如果您希望这些属性作为命名作用域属性,本文还介绍了实现这一目的的技术。这应该减轻你目前的scope[ngModel.$name]的工作方式,只是scope.name在你的指令。这将被视为……

scope: {
    'name': '='
    [...] // -- other attributes to be named on scope
}

还可以在博客中探讨如何使用@字符与=在作用域上传递{{ interpolated }}值的用法。只是…

  • @用于向指令
  • 传递一个字符串值
  • =用于创建一个传递到指令
  • 的对象的双向绑定。
  • ,允许一个外部函数被传入指令并被调用