2014-09-04 2 views
2

Эта функция должна использовать первую букву для каждого слова ввода. Но угловой бросает меня «RangeError: максимальный размер стека вызовов». И только becouse этого '' пространства на линии 9.angular.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

ответ

2

Проблема здесь

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

Это добавляет вам дополнительное пространство каждый раз, когда вы запускаете функцию.

Угловой работает так, как он управляет циклами.

В любое время, когда обнаруживается изменение одной из переменных, выполняется другой цикл.

Здесь из-за дополнительного пространства строка изменяется в бесконечном цикле, и поэтому угловые матрицы.

Уродливые решение добавить после

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

+1

Я бы сделал что-то вроде этого inputValue.split ('') .map (function (element) {return element.substring (0, 1) .toUpperCase() + element.substring (1)}) .присоединиться(' '); –

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

Ваш ответ замечательный, но он выдает неопределенную ошибку, когда пользователь очищает все данные. чтобы избежать этого, вы можете обернуть свою функцию замены, например, if (typeof scope.ngModel! == 'undefined') { scope.ngModel = scope.ngModel.replace (/^(.) | \ s (.)/g, function (v) {return v.toUpperCase();}); }); } –

1

Проблема не '' на линии 9, как вы предложили, но ваше использование modelCtrl. Когда вы используете modelCtrl.$setViewValuemodelCtrl снова запустите все $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 = ''; 
} 
+1

Давид Майкл Ганг прав. Мое решение не будет использовать слова в текстовом поле и его волю. – Nikolas

Смежные вопросы