Apa perbedaan antara ngModel. $ ModelValue dan ngModel. $ ViewValue

94

Saya memiliki petunjuk ckEditor berikut. Di bagian bawah ada dua variasi yang telah saya lihat dari contoh cara mengatur data di editor:

app.directive('ckEditor', [function () {
    return {
        require: '?ngModel',
        link: function ($scope, elm, attr, ngModel) {

            var ck = null;
            var config = attr.editorSize;
            if (config == 'wide') {
                ck = CKEDITOR.replace(elm[0], { customConfig: 'config-wide.js' });
            } else {
                ck = CKEDITOR.replace(elm[0], { customConfig: 'config-narrow.js' });
            }


            function updateModel() {
                $scope.$apply(function () {
                    ngModel.$setViewValue(ck.getData());
                });
            }

            $scope.$on('modalObjectSet', function (e, modalData) {
                // force a call to render
                ngModel.$render();
            });

            ck.on('change', updateModel);
            ck.on('mode', updateModel);
            ck.on('key', updateModel);
            ck.on('dataReady', updateModel);

            ck.on('instanceReady', function () {
                ngModel.$render();
            });

            ck.on('insertElement', function () {
                setTimeout(function () {
                    $scope.$apply(function () {
                        ngModel.$setViewValue(ck.getData());
                    });
                }, 1000);
            });

            ngModel.$render = function (value) {
                ck.setData(ngModel.$modelValue);
            };

            ngModel.$render = function (value) {
                ck.setData(ngModel.$viewValue);
            };
        }
    };
}])

Dapatkah seseorang memberi tahu saya apa perbedaan antara:

ck.setData(ngModel.$modelValue);
ck.setData(ngModel.$viewValue);

Dan mana yang harus saya gunakan. Saya melihat dokumentasi sudut dan dikatakan:

$viewValue

Actual string value in the view.

$modelValue

The value in the model, that the control is bound to.

Saya tidak mengerti apa yang penulis maksud ketika dia menulis ini di dokumen :-(

Samantha JT Star
sumber

Jawaban:

151

Anda melihat dokumentasi yang benar, tetapi mungkin saja Anda sedikit bingung. The $modelValuedan $viewValuememiliki satu perbedaan yang berbeda. Ini dia:

Seperti yang sudah Anda catat di atas:

$viewValue:Nilai string (atau Objek) aktual dalam tampilan.
$modelValue:Nilai dalam model, yang terikat dengan kontrol.

Saya akan berasumsi bahwa ngModel Anda mengacu pada <input />elemen ...? Jadi Anda <input>memiliki nilai string yang ditampilkan kepada pengguna, bukan? Tapi model sebenarnya mungkin versi lain dari string itu. Misalnya, input mungkin menampilkan string '200'tetapi <input type="number">(misalnya) sebenarnya akan berisi nilai model 200sebagai integer. Jadi representasi string yang Anda "lihat" di <input>adalah ngModel.$viewValuedan representasi numerik akan menjadi ngModel.$modelValue.

Contoh lain akan menjadi di <input type="date">mana $viewValueakan menjadi sesuatu seperti Jan 01, 2000dan $modelValueakan menjadi Dateobjek javascript sebenarnya yang mewakili string tanggal itu. Apakah itu masuk akal?

Saya harap itu menjawab pertanyaan Anda.

pemain tenis
sumber
Jadi pada dasarnya, $viewValueapakah selalu berupa string?
cdmckay
7
Sebagai docs mengatakan: $viewValue: Actual string value in the view.. Jadi iya.
pemain tenis
7
Catatan lain. Ketika <input type="text">nilai kosong, $modelValueproperti undefined, sedangkan $viewValueadalah ''string kosong. Ini bisa membuat perbedaan jika Anda mengendus "panjang" $modelValueyang tidak akan berhasil, tetapi $viewValueakan.
BradGreens
8
Itu $viewValuetidak selalu berupa string. Ini adalah string untuk arahan inti Angular saat ini, tetapi mungkin primitif atau Objek dalam kontrol kustom Anda. Contoh yang baik, adalah <input file="type">komponen, di mana viewValue berisi FileListobjek dengan file yang dilampirkan oleh pengguna. Dokumen Angular sedang bingung tentang hal ini sekarang dan harus diperbarui.
demisx
4
Juga tidak jika input tidak valid, $ modelValue tidak akan disetel. Yaitu, jika Anda memiliki <input ng-minlength = "8" ...> dan Anda hanya memasukkan 5 karakter, $ viewValue akan menampilkan 5 karakter tersebut tetapi $ modelValue tidak akan ada.
honkskillet
27

Anda bisa melihat hal-hal seperti ini:

  • $modelValue adalah API eksternal Anda, artinya, sesuatu yang diekspos ke pengontrol Anda.
  • $viewValue adalah API internal Anda, Anda harus menggunakannya hanya secara internal.

Saat mengedit $viewValue, metode render tidak akan dipanggil, karena ini adalah "model yang dirender". Anda harus melakukannya secara manual, sedangkan metode rendering akan dipanggil secara otomatis setelah $modelValuemodifikasi.

Namun, informasinya akan tetap konsisten berkat $formatters dan $parsers:

  • Jika Anda berubah $viewValue,$parsers akan menerjemahkannya kembali ke $modelValue.
  • Jika Anda berubah $modelValue, $formattersakan mengubahnya menjadi $viewValue.
Vianney Dupoy de Guitard
sumber
Saat mengedit $ viewValue, metode render tidak akan dipanggil. Jika Anda mengubah $ viewValue, $ parsers akan menerjemahkannya kembali ke $ modelValue.means $ modelvalue change. Dan metode rendering akan dipanggil secara otomatis setelah modifikasi $ modelValue. Jadi secara tidak langsung, ketika $ viewValue berubah, metode render dipanggil. Apakah itu ?
Mukund Kumar
1
Anda perlu mempelajari pipeline pengikatan dua arah Angular ngModel untuk memahami cara kerjanya. Saat memperbarui $viewValuemelalui setViewValue(viewValue)metode, parser / validator menendang (jika ada) dan menguraikannya viewValueke modelValue, memvalidasinya, menulisnya ke cakupan, lalu memulai viewChangeListeners. Saat digest berikutnya berjalan, nilai model diambil dari scope dan dibandingkan dengan $ modelValue di controller: github.com/angular/angular.js/blob/master/src/ng/directive/… . Jika mereka sama (dan mereka akan sama dalam skenario Anda), maka itu kembali.
demisx
18

Angular harus melacak dua tampilan data ngModel- ada data seperti yang terlihat oleh DOM (browser) dan kemudian ada representasi diproses Angular dari nilai-nilai tersebut. Ini $viewValueadalah nilai sisi DOM. Jadi, misalnya, di <input>file$viewValue adalah apa yang pengguna mengetik di browser mereka.

Setelah seseorang mengetik sesuatu <input>kemudian $viewValuediproses oleh $ parsers dan diubah menjadi tampilan Angular dari nilai yang dipanggil$modelValue .

Jadi Anda dapat menganggap $modelValuesebagai versi nilai yang diproses sudut, nilai yang Anda lihat dalam model, while$viewValue versi mentahnya.

Untuk mengambil satu langkah lebih jauh, bayangkan kita melakukan sesuatu yang mengubah file $modelValue. Angular melihat perubahan ini dan memanggil $ formatters untuk membuat pembaruan $viewValue(berdasarkan $ modelValue baru) untuk dikirim ke DOM.

KayakDave
sumber
maksudmu $ modelValue atau $ modelView ?? Jika $ modelValue, perbaiki kesalahan ketik tersebut.
Plankton