【问题标题】:What's a truly "Angularesque" way to implement maxlength on a textarea field?在 textarea 字段上实现 maxlength 的真正“Angularesque”方式是什么?
【发布时间】:2014-07-29 00:21:07
【问题描述】:

我正在编写一个指令以在 textarea 字段(HTML 版本

(function () {
'use strict';
var myAppModule = angular.module('myApp', []);
myAppModule.controller('MyController', function($scope) {
    $scope.textareaText = "";
});

myAppModule.directive('myMaxlength', ['$compile', '$log', function($compile, $log) {
    return {
        priority: 10000,
        restrict: 'A',
        require: 'ngModel',
        compile: function (elem, attrs) {
            elem.attr("ng-trim", "false");
            return function(scope, linkElem, linkAttrs, ctrl) {
                var maxlength = parseInt(linkAttrs.myMaxlength, 10);
                ctrl.$parsers.push(function (value) {
                    $log.info("In parser function value = [" + value + "].");
                    if (value.length > maxlength)
                    {
                        $log.info("The value [" + value + "] is too long!");
                        value = value.substr(0, maxlength);
                        ctrl.$setViewValue(value);
                        ctrl.$render();
                        $log.info("The value is now truncated as [" + value + "].");
                    }
                    return value;
                });
            };
        }
    };
}]);
})();

这几乎可以工作(见 JSFIDDLE here 注意:这个小提琴已经用下面选择的解决方案进行了更新,但上面的代码仍然存在这里提到的问题。)。它正确地限制了进入模型的字符,并将其渲染回显示器。但是,您可以继续输入空格以超过指定的最大长度。多余的空间不会进入模型,但会使显示混乱。我相信这与 ng-trim 有关。如您所见(在代码 sn-p 中),我在编译函数中设置了属性,但到那时为时已晚。有些人建议在你的编译函数中手动调用编译来强制 AngularJS 识别动态添加的属性,但这“似乎”是创建另一个副本并且不能解决显示问题。将ng-trim="false" 放在 textarea 元素上是可行的,但我想要一个干净的解决方案,用户需要做的就是添加一个指定最大长度的属性。

这是另一个示例(请参阅 JSFIDDLE here),在我看来它并不像“Angularesque”,但可以完成工作。

(function () {
'use strict';
var myAppModule = angular.module('myApp', []);
myAppModule.controller('MyController', function($scope) {
    $scope.textareaText = true;
});
myAppModule.directive('myMaxlength', ['$log', function($log) {
    return {
        restrict: 'A',
        link: function (scope, elem, attrs) {
            var maxlength = parseInt(attrs.myMaxlength, 10);
            $log.info("maxlength=[" + maxlength + "]");
            elem.bind('keydown', function (event) {
                $log.info("elem.val().length=[" + elem.val().length + "]");

                if (elem.val().length >= maxlength)
                {
                    // Void event Except backspace
                    if (event.keyCode != 8){
                        event.preventDefault();
                    }
                }
            });
        }
    };
}]); 
})();

那么,在 textarea 字段上实现 maxlength 的真正“Angularesque”方式是什么?提前谢谢!

【问题讨论】:

  • @T.J.Crowder - 没问题。谢谢参观。我不是想在这里创造文字,但认为 Angularesque 会让读者准确了解我所追求的。
  • 确实如此,非常简洁。 :-)
  • 不是 angularesque 但是,你试过 HTML5 的 textarea maxlength 属性吗?它似乎完全符合您的要求。
  • @FabrícioMatté - 谢谢,但我必须支持旧版浏览器,因此不能指望 HTML5。

标签: javascript jquery html angularjs


【解决方案1】:

您可以在 html 文件中的输入字段上使用 ngMaxlength 参数(此处的文档:https://docs.angularjs.org/api/ng/directive/input

例如

<input type="text" ng-model="myRestrictedText" ng-maxlength="10"/>

【讨论】:

  • 但是......问题是关于textarea,而不是input。它就在标题中。还有小提琴。
  • @emiidee 谢谢你,但我已经看过了。在您只需要验证的某些情况下,这很有帮助。但是,我希望在输入无效之前对其进行限制。 (见jsfiddle.net/ksevksev/YWq7g)。谢谢!
  • 原生 html 的 maxlength 属性使您在达到最大值后无法输入任何文本:w3schools.com/tags/att_input_maxlength.asp 这是您要找的吗?
  • @emiidee 再次感谢,但我正在处理一个 textarea 元素 (w3schools.com/tags/tag_textarea.asp)。此外,我必须支持旧版浏览器,因此 textarea 的新 HTML5 maxlength 属性无法让我到达我需要去的地方。
【解决方案2】:

您可以使用$attr.$set()(请参阅doc)以ngModel 可以识别的方式添加ng-trim 属性。

在编译函数中更改这行代码:

elem.attr("ng-trim", "false");

到这里:

attrs.$set("ngTrim", "false");

注意:记得把属性值改为camelCase

你也可以在链接函数中做(不需要编译函数):

linkAttrs.$set("ngTrim", "false");

jsfiddle: http://jsfiddle.net/J7MJF/7/

【讨论】:

    猜你喜欢
    • 2019-02-17
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2013-06-24
    • 2020-06-25
    • 1970-01-01
    相关资源
    最近更新 更多