2013-11-22 92 views
4

我有一个表单,它有一个输入字段和三个复选框。根据选择哪个复选框,该字段上的最大长度需要更改。我有这样ng-maxlength为什么不重新评估?

<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改变它的价值。这一切工作正常,我可以看到在$范围内更改的值。但是,我最初的最大长度仍然在应用中。达到初始最大字符数后弹出以下错误消息。为什么?

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

回答

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; 
        } 
       } 
      }); 
     } 
    } 
})(); 
+0

这几乎可行;在任何一种情况下,maxLengthValidator()都应该返回值,否则验证错误信息不能正确地使用FORMA.COMPONENTNAME。$ error.minlength来报告。 –

+1

@TimBoudreau:你的意思是maxlength? – epitka

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. 
}) 
+0

走到angularjs.org,寻找在$表的文档,并且无法找到任何:( – epitka

+0

'$ watch'is上['$ scope'类型(HTTP可用的方法://文档。 angularjs.org/api/ng.$ro​​otScope.Scope#methods_$watch)。 – Stewie

+0

@basarat:如果我正确理解这一点,我会从ctrl。$ parsers和ctrl。$ formatters中删除验证器,并重新添加一个新的我还需要调用$ scope.apply? – epitka