2014-11-25 5 views
1

Я хотел бы создать директиву для элемента управления ввода, который форматирует число с X числом десятичных знаков, когда вход не имеет фокуса. Когда вход имеет фокус, я хотел бы, чтобы число отображалось неформатированным (без запятых).Угловая директива фильтра формата number для ввода с использованием NgModel

Я почти там, со следующим кодом. Когда вы нажимаете внутри ввода, текст изменяется, и когда вы нажимаете (размываете событие), текстовые форматы снова. Однако, если я изменяю значение на входе, то события, похоже, меняются вокруг, а событие размытия ничего не делает. Затем, если вы снова щелкните в поле ввода, значение будет форматироваться, когда оно не должно, а событие размытия будет изменяться, когда оно должно форматироваться.

Чтобы использовать директиву, вы можете просто сделать

<input number-format ng-model="myValue" decimals="numberOfDecimals" /> 

Вот директива

App.directive('numberFormat', ['$filter', '$parse', function ($filter, $parse) { 
    return { 
     require: 'ngModel', 
     link: function (scope, element, attrs, ngModelController) { 
      var decimals = $parse(attrs.decimals)(scope); 

      ngModelController.$parsers.push(function (data) { 
       //convert data from view format to model format 
       return $filter('number')(data, decimals); //converted 
      }); 

      ngModelController.$formatters.push(function (data) { 
       //convert data from model format to view format 
       return $filter('number')(data, decimals); //converted 
      }); 

      element.bind('focus', function() { 
       element.val(ngModelController.$modelValue); 
      }); 

      element.bind('blur', function() { 
       element.val(ngModelController.$viewValue); 
      }); 
     } 
    } 
}]); 
+0

С тем, как вы определили '$ parsers', директива будет хранить форматированный номера в модели (то есть, если вы ввели' 123456', '$ modelValue' будет установлена ​​как' 123,456', который заканчивается как строка) каждый раз, когда вы редактируете соответствующее поле ввода. Вместо использования '$ parsers' и' $ formatters', почему бы не рассматривать '$ watch()' вместо значения модели? – miqid

+0

Я не уверен, что добавление наблюдателя - лучшая идея. Мне не нравится мысль о дополнительном наблюдателе для каждого экземпляра директивы. У меня могло быть возможно 50 из них на экране. 50 дополнительных наблюдателей звучат не очень хорошо. Должно быть в состоянии сделать это без наблюдателя. – Gillardo

+0

Ну, если вы настаиваете, вот незначительные изменения, которые должны сделать трюк. Вы ничего не говорите о проверке модели, поэтому я предполагаю, что вы в порядке с этим, http://plnkr.co/edit/wSflQs9bXYvihL5jUrvc?p=preview – miqid

ответ

3

Обсуждение в комментариях вопрос, как представляется, помогли ОР.

$parsers заставлял вводимые пользователем значения вводить в значение модели в качестве формата номера фильтра. Например, если было введено значение 123456, значение базовой модели будет установлено на 123,456. Дело здесь в том, что значение модели должно хранить исходный ввод пользователя, а не пользовательский ввод после применения форматирования. Простая реализация для анализа пользовательского ввода для $parsers будет использовать parseFloat(), например, так:

ngModelController.$parsers.push(function (data) { 
    return parseFloat(data); 
}); 

Чтобы быть в безопасности, эта функция синтаксического анализа должна быть улучшена, чтобы приспособить для плохого пользовательского ввода. Я привел рудиментарный пример этого в моем демонстрационном Plunker.

При размытии значение в поле ввода должно быть настроено на отфильтрованную версию значения модели.

DEMO

+0

Не мог попросить лучшего ответа! Еще раз спасибо – Gillardo

+0

Работает как волшебство! благодаря :) – Jin

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