Форматирующие и парсеры ngModel

103

Я разместил этот же вопрос в другой форме, но никто не ответил. Я не получаю четкого представления о том, что форматеры и парсеры делают в angular js.

По определению, оба средства форматирования и синтаксические анализаторы похожи на меня. Возможно, я ошибаюсь, так как я новичок в этом angularjs.

Определение форматеров

Массив функций, выполняемых в виде конвейера при изменении значения модели. Каждая функция вызывается по очереди, передавая значение следующей. Используется для форматирования / преобразования значений для отображения в элементе управления и проверки.

Определение парсеров

Массив функций для выполнения в виде конвейера всякий раз, когда элемент управления считывает значение из DOM. Каждая функция вызывается по очереди, передавая значение следующей. Используется для очистки / преобразования значения, а также для проверки. Для проверки парсеры должны обновлять состояние действительности с помощью $ setValidity () и возвращать undefined для недопустимых значений.

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

RONE
источник
2
Средства форматирования изменяют отображаемое значение модели, например отображение (123) 123-1234номера телефона. Парсеры читают данные каждый раз, когда они изменяются, и обычно используются для установки состояния ввода $ valid. В документах есть примеры обоих.
km6zla

Ответы:

155

Эта тема была очень хорошо освещена в связанном вопросе: как сделать двустороннюю фильтрацию в AngularJS?

Подвести итоги:

  • Средства форматирования изменяют способ отображения значений модели в представлении.
  • Парсеры изменяют способ сохранения значений представления в модели.

Вот простой пример, основанный на примере из документации API NgModelController :

  //format text going to user (model to view)
  ngModel.$formatters.push(function(value) {
    return value.toUpperCase();
  });

  //format text from the user (view to model)
  ngModel.$parsers.push(function(value) {
    return value.toLowerCase();
  });

Вы можете увидеть это в действии: http://plnkr.co/UQ5q5FxyBzIeEjRYYVGX?plnkr=legacy

<input type="button" value="set to 'misko'" ng-click="data.name='misko'"/>
<input type="button" value="set to 'MISKO'" ng-click="data.name='MISKO'"/>
<input changecase ng-model="data.name" />

Когда вы вводите имя в (от вида к модели), вы увидите, что модель всегда в нижнем регистре. Но когда вы нажимаете кнопку и программно меняете имя (модель для просмотра), поле ввода всегда отображается в верхнем регистре.

j.wittwer
источник
2
есть ли способ установить это изменение по типу пользователя? Вы говорите «программно», но я пытаюсь отформатировать $ viewValue, когда пользователь вводит данные, например, для форматирования номера кредитной карты
iamyojimbo,
3
@SavvasNicholas Если я не ошибаюсь, вы бы использовали ngModel.$setViewValue(transformedInput);для его установки и ngModel.$render();рендеринга из функции $ parsers.
Джейкоб Энсор,
В моем случае, что $formattersделать, немедленно отменяется $validators. ; (
Михаил Батцер
1
К вашему сведению, упомянутый plunkr больше не существует
Крис Браун
1
Я заметил, что форматер работает, только если вы нажмете кнопку, а не если вы
введете
6

Еще одно использование средств форматирования и синтаксических анализаторов - это когда вы хотите хранить даты в формате UTC и отображать их в локальном времени на входах, я создал для этого указанную ниже директиву datepicker и фильтр utcToLocal.

(function () {
    'use strict';

    angular
        .module('app')
        .directive('datepicker', Directive);

    function Directive($filter) {
        return {
            require: 'ngModel',
            link: function (scope, element, attr, ngModel) {
                element.addClass('datepicker');
                element.pickadate({ format: 'dd/mm/yyyy', editable: true });

                // convert utc date to local for display
                ngModel.$formatters.push(function (utcDate) {
                    if (!utcDate)
                        return;

                    return $filter('utcToLocal')(utcDate, 'dd/MM/yyyy');
                });

                // convert local date to utc for storage
                ngModel.$parsers.push(function (localDate) {
                    if (!localDate)
                        return;

                    return moment(localDate, 'DD/MM/YYYY').utc().toISOString();
                });
            }
        };
    }
})();

Он использует этот фильтр utcToLocal, который гарантирует, что введенная дата находится в правильном формате перед преобразованием в местное время.

(function () {
    'use strict';

    angular
        .module('app')
        .filter('utcToLocal', Filter);

    function Filter($filter) {
        return function (utcDateString, format) {
            if (!utcDateString) {
                return;
            }

            // append 'Z' to the date string to indicate UTC time if the timezone isn't already specified
            if (utcDateString.indexOf('Z') === -1 && utcDateString.indexOf('+') === -1) {
                utcDateString += 'Z';
            }

            return $filter('date')(utcDateString, format);
        };
    }
})();

moment.js используется для преобразования локальных дат в формат utc.

pickadate.js - используемый плагин datepicker

Джейсон
источник