2013-06-12 25 views
35

我正在嘗試做一個簡單的textarea與「這麼多字符剩餘」以及驗證。 當我使用ng-maxlength驗證表單時,只要長度達到最大長度,就會重置我的帳戶。以下是plunkr任何解決方法?ng-maxlength擰了我的模型

<body ng-controller="MainCtrl"> 
    <div ng-form="noteForm"> 
     <textarea ng-maxlength="15" ng-model="result"></textarea> 
     <p>{{15 - result.length}} chars remaining</p> 
     <button ng-disabled="!noteForm.$valid">Submit</button> 
    </div> 
    </body> 
+0

有趣的事情,但對我來說(採用了棱角分明1.4.7 +打字稿1.8.7)HTML屬性「最大長度」的用法有同樣的效果,這裏提到的「ng-maxLength」:在將一些大的值(大於定義的限制)直接設置爲模型後,模型中的值變爲未定義。從我的角度來看,這是Angular bug(就像上面提到的[user3232182](http://stackoverflow.com/users/3232182/user3232182))。可能甚至沒有與ng-maxLength直接關聯,而是與整個綁定機制有關。 – bkg

回答

55

當你的文字區域超過15個字符,result成爲undefined —這就是ng-min/maxlength指令是如何工作的。我想你必須寫出自己的指令。這裏是一個指令後15個字符,這將阻止輸入:

<textarea my-maxlength="15" ng-model="result"></textarea> 
app.directive('myMaxlength', function() { 
    return { 
    require: 'ngModel', 
    link: function (scope, element, attrs, ngModelCtrl) { 
     var maxlength = Number(attrs.myMaxlength); 
     function fromUser(text) { 
      if (text.length > maxlength) { 
      var transformedInput = text.substring(0, maxlength); 
      ngModelCtrl.$setViewValue(transformedInput); 
      ngModelCtrl.$render(); 
      return transformedInput; 
      } 
      return text; 
     } 
     ngModelCtrl.$parsers.push(fromUser); 
    } 
    }; 
}); 

fiddle


更新:允許超過15個字符,但禁用時提交按鈕計數超過15:

link: function (scope, element, attrs, ngModelCtrl) { 
    var maxlength = Number(attrs.myMaxlength); 
    function fromUser(text) { 
     ngModelCtrl.$setValidity('unique', text.length <= maxlength); 
     return text; 
    } 
    ngModelCtrl.$parsers.push(fromUser); 
} 

fiddle

+1

非常感謝。我很喜歡它超越並像Twitter一樣顯示負面效果,但這已經足夠了:) – Riz

+0

@Riz,查看更新後的答案。 –

+0

輝煌!這應該是默認的ng-maxlength行爲。也許你可以把它推到角度;) – Riz

52

或者你可以添加標準的HTML maxlength屬性旁邊的ng-maxlength

<form name="myForm"> 
    <textarea name="myTextarea" ng-maxlength="15" maxlength="15" ng-model="result"></textarea> 
    <span class="error" ng-show="myForm.myTextarea.$error.maxlength"> 
     Reached limit! 
    </span> 
</form> 

這將切斷的「15」字,爲maxlength一直做,並且另外ng-maxlength可以讓你在到達極限顯示自定義消息。

Click for Plunker Example

+0

我認爲這是迄今爲止最好的方法。 –

+0

這也覆蓋了大於max的文字粘貼,謝謝。 –

+0

是的,這是我如何得到它的工作,雖然它沒有那麼高效,因爲我需要在兩個屬性中重複相同的值... –

3

我認爲這應該被記錄爲對角的錯誤。它不應該清除你的模型。我有一個指令,將下拉選擇鏈接到一個文本框,只要你插入一個字,使它超過最大長度,然後它清除我的模型和文本框。它應該當驗證者認爲模型無效時,不能清除模型。

3

我正在使用的另一種方法是保留與ng-maxlength驗證程序相同的行爲,但通過額外屬性'actual-length'反饋長度。

app.directive('newMaxlength', function() { 
     return { 
      require: 'ngModel', 
      scope: { 
       maxlength: '=newMaxlength', 
       actualLength: '=' 
      }, 
      link: function (scope, elem, attr, ngModelCtrl) { 

       function validate(ctrl, validatorName, validity, value) { 
        ctrl.$setValidity(validatorName, validity); 
        return validity ? value : undefined; 
       } 

       var maxlength = parseInt(scope.maxlength, 10); 
       var maxLengthValidator = function (value) { 
        scope.actualLength = value ? value.length : 0; 
        return validate(ngModelCtrl, 'maxlength', ngModelCtrl.$isEmpty(value) || value.length <= maxlength, value); 
       }; 

       ngModelCtrl.$parsers.push(maxLengthValidator); 
       ngModelCtrl.$formatters.push(maxLengthValidator); 
      } 
     }; 
    }); 

這裏是額外的屬性的元素:

<textarea name="myTextarea" new-maxlength="100" actual-length="actualLength" ng-model="text"></textarea> 
0

我有一個更好的解決方案,我認爲:可設置最大長度,如果NG-最大長度是存在的。

這樣你在同一時間這兩個功能:如果你添加一個名稱屬性textarea的則在範圍創造了價值的新屬性的角度驗證+文本切斷

.directive("textarea", function() { 
    return { 
     restrict: "E", 
     link: function (scope, elem, attrs) { 
      if (angular.isDefined(attrs["ngMaxlength"])) { 
       attrs.$set("maxlength", attrs["ngMaxlength"]); 
      } 
     } 
    }; 
}) 
+1

這不會在ie 9中工作,因爲attr maxlength只能在HTML5 – alecellis1985

+0

中工作。但我想你可以使用polyfills來解決這種情況。找到的示例:http://stackoverflow.com/questions/1125482/how-to-impose-maxlength-on-textarea-in-html-using-javascript/1125521#1125521,雖然我還沒有試圖讓它在指令,但我想這並不難。謝謝你的提示! –

16

表單,可以用來獲取字符計數器的長度。

<body ng-controller="MainCtrl"> 
    <div ng-form="noteForm"> 
    <textarea ng-maxlength="15" name="noteItem" ng-model="result"></textarea> 
    <p>{{15 - noteForm.noteItem.$viewValue.length}} chars remaining</p> 
    <button ng-disabled="!noteForm.$valid">Submit</button> 
    </div> 
</body> 

更新您的plnkr

+1

這個很好,不需要額外的代碼。謝謝! – yarl

+1

爲什麼這個答案沒有更多upvotes。這麼簡單快捷並且重要。 :D謝謝,是的,請 – BrettS

13

隨着doc說,在$驗證功能集模型未定義當有效期變爲無效。

但是,我們仍然可以通過簡單地將allowInvalid: true添加到ng-model-options來防止此行爲。

所以,只要修改您的代碼,如:

<body ng-controller="MainCtrl"> 
    <div ng-form="noteForm"> 
     <textarea ng-maxlength="15" ng-model="result" 
      ng-model-options="{ allowInvalid: true }"></textarea> 
     <p>{{15 - result.length}} chars remaining</p> 
     <button ng-disabled="!noteForm.$valid">Submit</button> 
    </div> 
</body> 
+2

這應該是正確的答案 –

+0

謝謝我的男人! – Wax