Формат валюты 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

Убедитесь, что вы действительно возвращаете действительное значение из своих функций.

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