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

Angularjs 为什么不重新评估ng maxlength?,angularjs,angularjs-scope,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-

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

 <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}">

这是ng maxlength的预期行为。来源核实:

该值仅解析一次并缓存:

 var maxlength = int(attr.ngMaxlength);
如果您想观察更改,您需要创建自己的指令,该指令使用

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

经过大量的尝试和错误,这里是我需要的指令。如果你有任何建议或改进,请与我分享,我只有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;
                    }
                } 
            });
        }
    }
})();

转到angularjs.org并查找$watch上的文档,但找不到任何内容:(
$watch
是上可用的方法。@basarat:如果我理解正确,我将从ctrl.$parsers和ctrl.$formatters中删除验证程序,并使用新的最大长度重新添加。我是否还需要调用$scope.apply?@epitka“我将从ctrl.$parsers和ctrl.$formatters中删除验证程序,并使用新的最大长度重新添加。”是,“我还需要调用$scope.apply吗?”“不是。手表是在摘要循环中执行的,所以作用域。$apply实际上会抛出一个错误。@basarat:请您提供一个提琴示例,看看您推荐的方法。这几乎可以工作;maxLengthValidator()应该
返回值;
在这两种情况下,或者使用
FORM.COMPONENTNAME.$error.minlength
@TimBoudreau:您是说maxlength没有正确报告验证错误消息?
scope.$watch(attr.namespaceMaxLength,function(){
// clear old validator. Add new one. 
})
(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;
                    }
                } 
            });
        }
    }
})();