NgModel Formatters and Parsers

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

По определению, как Formatters, так и Parsers выглядят похожими на меня. Может быть, я ошибаюсь, поскольку я новичок в этом angularjs.

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

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

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

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

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

Ответ 1

В этом вопросе был очень хорошо рассмотрен связанный с этим вопрос: Как выполнить двустороннюю фильтрацию в angular.js?

Подводя итог:

  • Formatters изменяют, как будут отображаться значения модели в представлении.
  • Parsers изменяют способ сохранения значений в модели.

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

  //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

<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" />

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

Ответ 2

Еще одно использование для форматировщиков и парсеров - это когда вы хотите хранить даты в 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