ng-maxlength拧了我的模型

我试图做一个简单的textarea与“这么多字符剩余”与validation。 当我使用ng-maxlength来validation我的表单时,只要长度达到最大长度,它就会重置我的帐户。 这是PLUNK任何解决方法?

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

当你的textarea超过15个字符时, result变得undefined – 这就是ng-min/maxlength指令的工作方式。 我想你必须写出自己的指令。 这是一个指令,将阻止15个字符后的input:

 <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); } }; }); 

小提琴


更新:允许超过15个字符,但在计数超过15时禁用提交button:

 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); } 

小提琴

另外,你可以在ng-maxlength旁边添加标准的html 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可以让你在达到极限时显示自定义消息。

点击Plunker示例

如果给textarea添加一个name属性,则在窗体范围内创build一个新的属性值,您可以使用该属性来获取字符计数器的长度。

 <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

正如文档所述,$ validate函数设置的模型在undevalid时有效性变为无效。

但是,我们仍然可以通过简单地向ng-model-options添加allowInvalid: true来防止这种行为。

所以,只需修改你的代码:

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

我认为这应该被logging为angular度上的错误。 它不应该清除你的模型。我有一个指令,将下拉select链接到一个文本框,只要你插入一个单词,使其超过最大长度,那么它清除我的模型和文本框。它应该当它认为模型是无效的时,成为一个validation者不能清除你的模型。

我正在使用的另一种方法是保留与ng-maxlengthvalidation程序相同的行为,但通过额外的属性“实际长度”反馈长度。

 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> 

我有一个更好的解决scheme,我想:设置最大长度,如果ng-maxlength存在。

这样你就可以同时得到两个function:angular度validation+文本截断

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