angular.js大写每个单词

时间:2014-09-04 14:15:21

标签: angularjs

此函数应为输入中的每个单词的首字母大写。但是角度让我感到“RangeError:超出了最大调用堆栈大小”。而且只是因为第9行的空间。

myApp.directive('capitalizeFirst', function(uppercaseFilter, $parse) {
   return {
     require: 'ngModel',
     link: function(scope, element, attrs, modelCtrl) {
        var capitalize = function(inputValue) {
           var capitalized = inputValue.split(' ').reduce(function(prevValue, word){
            return  prevValue + word.substring(0, 1).toUpperCase() + word.substring(1)+' ';
        }, '');
           if(capitalized !== inputValue) {
              modelCtrl.$setViewValue(capitalized);
              modelCtrl.$render();
            }         
            return capitalized;
         }
         var model = $parse(attrs.ngModel);
         modelCtrl.$parsers.push(capitalize);
         capitalize(model(scope));
     }
   };
});

这里是小提琴

http://jsfiddle.net/YyYnM/205/

有人可以向我解释一下吗?我现在想把它搞清楚一个小时。

3 个答案:

答案 0 :(得分:2)

我不知道你的代码有什么问题,但试试这个。 DEMO

myApp.directive('capitalizeFirst', function (uppercaseFilter, $parse) {
    return {
        require: 'ngModel',
        scope: {
            ngModel: "="
        },
        link: function (scope, element, attrs, modelCtrl) {

            scope.$watch("ngModel", function () {
                scope.ngModel = scope.ngModel.replace(/^(.)|\s(.)/g, function(v){ return v.toUpperCase( ); });
            });
        }
    };
});

答案 1 :(得分:2)

问题出在这里

var capitalize = function(inputValue) {
           var capitalized = inputValue.split(' ').reduce(function(prevValue, word){
            return  prevValue + word.substring(0, 1).toUpperCase() + word.substring(1)+' ';
        }, '');

每次运行该功能时,它会为您增加一个额外的空间。

Angular以循环运行的方式工作。

每当检测到其中一个变量的变化时,它会运行另一个循环。

这里由于额外的空间,字符串在无限循环中被改变,因此角度死亡。

一个丑陋的解决方案是事后添加

capitalized = capitalized.substring(0, capitalized.length - 1);

答案 2 :(得分:1)

问题不在于您建议的第9行的'',而是您使用modelCtrl。当您使用modelCtrl.$setViewValue modelCtrl时,将再次运行所有$parsers。因此,它会递归调用capitalize函数,直到它从堆栈中出现。

要使输入大写,您需要做的就是推送一个将字符串更改为$parsers数组的函数。这将完成这项工作:

myApp.directive('capitalizeFirst', function(uppercaseFilter, $parse) {
   return {
     require: 'ngModel',
     link: function(scope, element, attrs, modelCtrl) {
        var capitalize = function(inputValue) {
           var capitalized = inputValue.split(' ').reduce(function(prevValue, word){
            return  prevValue + word.substring(0, 1).toUpperCase() + word.substring(1)+' ';
        }, '');        
            return capitalized;
         }
         modelCtrl.$parsers.push(capitalize);
     }
   };
});

function MyCtrl($scope) {
    $scope.name = '';
}