ngModel Formatters dan Parsers

103

Saya memposting pertanyaan yang sama dalam bentuk yang berbeda, tetapi tidak ada yang menjawab. Saya tidak mendapatkan gambaran yang jelas tentang apa yang dilakukan para Formatters dan Parsers di angular js.

Menurut definisi, baik Formatters dan Parsers terlihat mirip dengan saya. Mungkin saya salah, karena saya baru mengenal angularjs ini.

Definisi Pemformat

Larik fungsi yang akan dijalankan, sebagai pipeline, setiap kali nilai model berubah. Setiap fungsi dipanggil, pada gilirannya, meneruskan nilai ke fungsi berikutnya. Digunakan untuk memformat / mengubah nilai untuk ditampilkan di kontrol dan validasi.

Definisi Parser

Larik fungsi yang akan dijalankan, sebagai pipeline, setiap kali kontrol membaca nilai dari DOM. Setiap fungsi dipanggil, pada gilirannya, meneruskan nilai ke fungsi berikutnya. Digunakan untuk membersihkan / mengubah nilai serta validasi. Untuk validasi, parser harus memperbarui status validitas menggunakan $ setValidity (), dan mengembalikan tidak ditentukan untuk nilai yang tidak valid.

Tolong bantu saya untuk memahami kedua fitur dengan contoh sederhana. Ilustrasi sederhana dari keduanya akan dihargai.

RONE
sumber
2
Pemformat mengubah nilai model yang ditampilkan, seperti menampilkan (123) 123-1234nomor telepon. Parser membaca data setiap kali berubah dan biasanya digunakan untuk menyetel status input $ valid. Dokumen memiliki contoh keduanya.
km6zla

Jawaban:

155

Topik ini dibahas dengan sangat baik dalam pertanyaan terkait: Bagaimana cara melakukan pemfilteran dua arah di AngularJS?

Untuk meringkas:

  • Format mengubah bagaimana nilai model akan muncul dalam tampilan.
  • Parser mengubah bagaimana nilai tampilan akan disimpan dalam model.

Berikut adalah contoh sederhana, membangun sebuah contoh dalam dokumentasi 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();
  });

Anda dapat melihatnya beraksi: 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" />

Saat Anda mengetik nama di (view to model), Anda akan melihat bahwa model selalu huruf kecil. Namun, saat Anda mengklik tombol dan secara programatik mengubah nama (model untuk dilihat), kolom input selalu dalam huruf besar.

j. wittwer
sumber
2
apakah ada cara untuk menyetel perubahan ini saat pengguna mengetik? Anda mengatakan "secara terprogram", tetapi saya mencoba untuk membuat $ viewValue diformat saat pengguna memasukkan masukan, misalnya untuk pemformatan nomor kartu kredit
iamyojimbo
3
@SavvasNicholas Jika saya tidak salah, Anda akan menggunakan ngModel.$setViewValue(transformedInput);untuk menyetelnya dan ngModel.$render();merendernya dari fungsi $ parsers.
Jacob Ensor
Dalam kasus saya, apa yang $formattersdilakukan, segera dikembalikan oleh $validators. ; (
Mikhail Batcer
1
FYI, plunkr yang direferensikan tidak ada lagi
Chris Brown
1
Saya perhatikan pemformat hanya berfungsi jika Anda menekan tombol, bukan jika Anda mengetik nama ke dalam bidang
nuander
6

Penggunaan lain untuk pemformat dan pengurai adalah ketika Anda ingin menyimpan tanggal dalam waktu UTC dan menampilkannya dalam waktu lokal pada input, saya membuat direktif datepicker di bawah ini dan filter utcToLocal untuk ini.

(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();
                });
            }
        };
    }
})();

Ia menggunakan filter utcToLocal ini yang memastikan tanggal masukan dalam format yang benar sebelum mengonversi ke waktu lokal.

(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 digunakan untuk mengubah tanggal lokal ke utc.

pickadate.js adalah plugin datepicker yang digunakan

Jason
sumber