2014-09-04 83 views
2

該函數應該大寫輸入中每個單詞的首字母。但角是扔我「RangeError:超過最大調用堆棧大小」。而且,只有becouse上線9angular.js大寫每個單詞

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/

有人可以解釋這樣對我?我現在試圖弄清楚這一個小時。

+2

似乎'capitalized'絕不等於'inputValue',因爲要附加在減少功能的空間('')的值。 – Axarydax 2014-09-04 14:34:49

回答

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); 
+0

當我將修改拆分和空間添加到帶空格的字母時,我該怎麼辦?像這樣var capitalize = function(inputValue)var capitalized = inputValue.split('b').reduce(function(prevValue,word){ return prevValue + word.substring(0,1).toUpperCase()+ word .substring(1)+'b'; },''); 拋出相同的錯誤 – frog 2014-09-04 15:00:13

+1

我會做這樣的inputValue.split('').map(function(element){return element.substring(0,1).toUpperCase()+ element.substring(1)}) .join(''); – 2014-09-04 15:04:28

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(); }); 
      }); 
     } 
    }; 
}); 
+0

你的答案很好,但當用戶清除所有數據時會拋出未定義的錯誤。爲了避免這種情況,你可以包裝你的替換函數,如下所示:(typeof scope.ngModel!=='undefined')scope.ngModel = scope.ngModel.replace(/ ^(。)| \ s( 。)/ g,function(v){return v.toUpperCase();}); }); } – 2016-10-20 07:15:06

1

的問題不就行了9如你所說的'',但你的modelCtrl使用。當您使用modelCtrl.$setViewValuemodelCtrl將再次運行所有$parsers。因此,它會遞歸地調用你的函數,直到它離開堆棧。

爲了使輸入大寫,您只需要按下一個函數即可將字符串更改爲$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 = ''; 
} 
+1

David Michael Gang是對的。我的解決方案不會將文本框內的文字和他的意願大寫。 – Nikolas 2014-09-04 14:39:31

相關問題