为什么不重新评估ng-maxlength?

时间:2013-11-22 14:12:06

标签: angularjs angularjs-scope

我有一个表单,它有一个输入字段和三个复选框。根据选择的复选框,字段上的最大长度需要更改。我有一个像这样定义的输入字段

 <input placeholder="ID" type="text" id="form_ID" name="searchId" autofocus
 data-ng-model="vm.searchCriteria.searchId" data-ng-required="vm.isSearchIdRequired"
 data-ng-minlength="1" data-ng-maxlength="{{searchIdMaxLength}}"
 data-ng-class="{'input-error': vm.isSearchIdValid}">

和其中一个复选框

<input type="checkbox" id="checkbox1" class="hidden-field"
  data-ng-model="vm.searchCriteria.searchIdInSrId" data-ng-checked="vm.searchCriteria.searchIdInSrId"
 data-ng-change="processSearchIdOptionsChange()">

因此,每当用户更改选中的复选框时,processSearchIdOptionsChange都会被调用,searchIdMaxLength会更改其值。这一切都运行正常,我可以看到$ scope上的值被更改。但是,我的初始最大长度仍然适用。在达到初始最大字符数后弹出以下错误。为什么?

<span class="error" data-ng-show="(searchForm.$dirty &&  searchForm.searchId.$error.maxlength)">Too long!</span>

2 个答案:

答案 0 :(得分:2)

这是ng-maxlength的预期行为。从来源验证:https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js?source=c#L523

该值仅解析一次并缓存:

 var maxlength = int(attr.ngMaxlength);

如果您想观察更改,您需要创建自己的指令,使用类似

的指令
scope.$watch(attr.namespaceMaxLength,function(){
// clear old validator. Add new one. 
})

答案 1 :(得分:0)

经过大量的试验和错误后,这个指令就是我需要的。如果你有任何建议或改进分享它们,我只有7天的角度,javascript是我粗略的知识。

(function () {
    'use strict';

    angular.module('commonModule')
        .directive('srMaxlength', ['$window', srMaxlength]);

    function srMaxlength($window) {
        // Usage:
        // use if you need to switch max length validation dynamically based on
        // Creates:
        // removes old validator for max length and creates new one 
        var directive = {
            require: 'ngModel',
            link: link,
            restrict: 'A'
        };

        return directive;

        function link(scope, element, attrs, ctrl) {
            attrs.$observe("srMaxlength", function (newval) {
                var maxlength = parseInt(newval, 10);
                var name = "srMaxLengthValidator";

                for (var i = ctrl.$parsers.length - 1; i >= 0; i--) {
                    if (ctrl.$parsers[i].name !== undefined && ctrl.$parsers[i].name == name) {
                        ctrl.$parsers.splice(i, 1);
                    }
                }

                for (var j = ctrl.$formatters.length - 1; j >= 0; j--) {
                    if (ctrl.$formatters[j].name !== undefined && ctrl.$formatters[j].name == name) {
                        ctrl.$formatters.splice(j, 1);
                    }
                }

                ctrl.$parsers.push(maxLengthValidator);
                ctrl.$formatters.push(maxLengthValidator);

                //name the function so we can find it always by the name
                maxLengthValidator.name = name;

                function maxLengthValidator(value) {
                    if (!ctrl.$isEmpty(value) && value.length > maxlength) {
                        ctrl.$setValidity('maxlength', false);
                        return undefined;
                    } else {
                        ctrl.$setValidity('maxlength', true);
                        return value;
                    }
                } 
            });
        }
    }
})();