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


103

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

定義上、フォーマッターとパーサーはどちらも私に似ています。私はこのangularjsに慣れていないので、私は間違っているかもしれません。

フォーマッタの定義

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

パーサーの定義

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

簡単な例で両方の機能を理解できるようにしてください。両方の簡単な説明をいただければ幸いです。


2
フォーマッタ(123) 123-1234は、電話番号の表示など、モデルの表示値を変更します。パーサーはデータが変更されるたびにデータを読み取り、通常、入力の$ valid状態を設定するために使用されます。ドキュメントには両方の例があります。
km6zla 2014

回答:


155

このトピックは、関連する質問「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" />

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


2
この変更をユーザーの入力として設定する方法はありますか?「プログラムで」と言いますが、ユーザーが入力を入力するときに$ viewValueをフォーマットしようとしています。たとえば、クレジットカード番号のフォーマット
iamyojimbo

3
@SavvasNicholas私が間違っていなければ、ngModel.$setViewValue(transformedInput);それを設定ngModel.$render();して$ parsers関数からレンダリングするために使用します。
Jacob Ensor 2015

私の場合、何をするか$formattersはによってすぐに元に戻され$validatorsます。;(
ミハイル・バッサー

1
参考にした参照されたplunkrはもう存在しません
Chris Brown

1
フォーマッターが機能するのは、ボタンを押す場合のみであり、フィールドに名前を入力する場合ではないことに
気づき

6

フォーマッターとパーサーのもう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プラグインです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.