web-dev-qa-db-ja.com

ngModelフォーマッタとパーサー

同じ質問を別の形式で投稿しましたが、誰も答えませんでした。 angular jsでフォーマッターとパーサーが何をするのか明確に把握していません。

定義では、フォーマッターとパーサーの両方が私に似ています。たぶん私は間違っているのかもしれません、私はこのangularjsが初めてだからです。

フォーマッタの定義

モデル値が変更されるたびに、パイプラインとして実行する関数の配列。各関数が順番に呼び出され、値を次の要素に渡します。コントロールおよび検証で表示する値をフォーマット/変換するために使用されます。

パーサーの定義

コントロールがDOMから値を読み取るたびに、パイプラインとして実行する関数の配列。各関数が呼び出され、順番に値が渡されます。値と検証のサニタイズ/変換に使用されます検証のために、パーサーは$ setValidity()を使用して有効性状態を更新し、無効な値に対してundefinedを返す必要があります。

簡単な例で両方の機能を理解するのを手伝ってください。両方の簡単な説明をいただければ幸いです。

99
RAVI MONE

このトピックは関連する質問で非常によくカバーされていました: AngularJSで双方向フィルタリングを行う方法?

要約する:

  • フォーマッタは、モデル値がビューに表示される方法を変更します。
  • パーサーは、ビュー値がモデルに保存される方法を変更します。

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

(モデルへのビュー)に名前を入力すると、モデルが常に小文字であることがわかります。ただし、ボタンをクリックしてプログラムで名前(表示するモデル)を変更すると、入力フィールドは常に大文字になります。

153
j.wittwer

フォーマッタとパーサーのもう1つの使用法は、日付を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プラグインです

5
Jason