Формат валюты Angularjs в поле ввода с ng-model: как получить $formatters для каждого входа
Я искал везде для этого. Каждый переполнение стека имеет ответ, на самом деле он не работает. То же самое с примерами или примерами групп google из angular, включая документы.
Кажется простым. Я хочу, чтобы функция вызывалась на входе для каждой нажатой пользователем клавиши.
простой ввод с ng-моделью
<input class="form-control" ng-model="model.thisisnotfun" formatter type="text" required>
В соответствии со всем, что я читал. $formatters должны обновить значение от модели до представления, вызывающего любые функции в массиве $formatters. Они никогда не вызываются, когда я ввожу в поле ввода.
.directive('formatter', function ($filter, $parse) {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
ngModel.$formatters.push(
function (value) {
console.log('this only gets called on page load');
}
);
}
};
})
Я знаю, что есть много настраиваемых способов сделать это, что я уже сделал. Мне не нужна работа, я просто хочу знать, как правильно использовать $formatters для "форматирования" данных вида.
очень простой jsfiddle http://jsfiddle.net/fh7sB/4/
Спасибо за любую помощь.
Ответы
Ответ 1
$formatters
вызывается, когда модель обновляется, чтобы отформатировать значение, которое будет представлено пользователю. $parsers
делают обратное, то есть переводят значение из строки представления в реальную модель, например. число.
В разветвленной скрипке здесь: http://jsfiddle.net/9tuCz/ нажмите кнопку; он изменяет модель и снова запускает $formatters
.
Ответ 2
Я не мог заставить функцию $formatters работать так, как хотелось. Я также не мог найти ни одного примера того, что я искал где угодно, поэтому я собираюсь опубликовать свой ответ, если кому-то это понадобится.
Это директива для форматирования валюты в поле ввода с ng-model
.directive('uiCurrency', function ($filter, $parse) {
return {
require: 'ngModel',
restrict: 'A',
link: function (scope, element, attrs, ngModel) {
function parse(viewValue, noRender) {
if (!viewValue)
return viewValue;
// strips all non digits leaving periods.
var clean = viewValue.toString().replace(/[^0-9.]+/g, '').replace(/\.{2,}/, '.');
// case for users entering multiple periods throughout the number
var dotSplit = clean.split('.');
if (dotSplit.length > 2) {
clean = dotSplit[0] + '.' + dotSplit[1].slice(0, 2);
} else if (dotSplit.length == 2) {
clean = dotSplit[0] + '.' + dotSplit[1].slice(0, 2);
}
if (!noRender)
ngModel.$render();
return clean;
}
ngModel.$parsers.unshift(parse);
ngModel.$render = function() {
console.log('viewValue', ngModel.$viewValue);
console.log('modelValue', ngModel.$modelValue);
var clean = parse(ngModel.$viewValue, true);
if (!clean)
return;
var currencyValue,
dotSplit = clean.split('.');
// todo: refactor, this is ugly
if (clean[clean.length-1] === '.') {
currencyValue = '$' + $filter('number')(parseFloat(clean)) + '.';
} else if (clean.indexOf('.') != -1 && dotSplit[dotSplit.length - 1].length == 1) {
currencyValue = '$' + $filter('number')(parseFloat(clean), 1);
} else if (clean.indexOf('.') != -1 && dotSplit[dotSplit.length - 1].length == 1) {
currencyValue = '$' + $filter('number')(parseFloat(clean), 2);
} else {
currencyValue = '$' + $filter('number')(parseFloat(clean));
}
element.val(currencyValue);
};
}
};
})
Ответ 3
Убедитесь, что вы действительно возвращаете действительное значение из своих функций.
Что, вероятно, происходит, так как парсер возвращает одно и то же значение каждый раз, форматтер предполагает, что форматированный вывод не изменился бы так, чтобы он пропускал вызов.