2013-11-22 67 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