我正在写一个指令以在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有关。如您所见(在代码片段中),我在compile函数中设置了属性,但是到那时为时已晚。一些建议在编译函数中手动调用compile以强制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”方法是什么?先感谢您!

最佳答案

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

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

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

对此:
attrs.$set("ngTrim", "false");

注意:切记将属性值更改为 camelCase !

您也可以在链接函数中执行此操作(无需编译函数):
linkAttrs.$set("ngTrim", "false");

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

07-26 00:15
查看更多