Di knockout js saya melihat View Models dideklarasikan sebagai:
var viewModel = {
firstname: ko.observable("Bob")
};
ko.applyBindings(viewModel );
atau:
var viewModel = function() {
this.firstname= ko.observable("Bob");
};
ko.applyBindings(new viewModel ());
Apa perbedaan antara keduanya, jika ada?
Saya memang menemukan diskusi ini di grup google knockoutjs tetapi tidak benar-benar memberi saya jawaban yang memuaskan.
Saya dapat melihat alasannya jika saya ingin menginisialisasi model dengan beberapa data, misalnya:
var viewModel = function(person) {
this.firstname= ko.observable(person.firstname);
};
var person = ... ;
ko.applyBindings(new viewModel(person));
Tetapi jika saya tidak melakukan itu bedanya gaya mana yang saya pilih?
prototype
(metode yang sering, misalnya, mengambil data dari server dan memperbarui model tampilan yang sesuai). Namun Anda masih bisa dengan jelas mendeklarasikannya sebagai properti dari objek literal, jadi saya tidak bisa melihat perbedaan.Jawaban:
Ada beberapa keuntungan menggunakan fungsi untuk menentukan model tampilan Anda.
Keuntungan utama adalah bahwa Anda memiliki akses langsung ke nilai
this
yang sama dengan instance yang dibuat. Ini berarti Anda dapat melakukan:Jadi, komputer yang Anda hitung dapat diikat ke nilai yang sesuai
this
, bahkan jika dipanggil dari ruang lingkup yang berbeda.Dengan objek literal, Anda harus melakukan:
Dalam hal itu, Anda bisa menggunakan
viewModel
secara langsung dalam computable observable, tetapi ia langsung dievaluasi (secara default) sehingga Anda tidak bisa mendefinisikannya dalam objek literal, sepertiviewModel
yang tidak didefinisikan sampai setelah objek literal ditutup. Banyak orang tidak suka bahwa pembuatan model tampilan Anda tidak dienkapsulasi menjadi satu panggilan.Pola lain yang dapat Anda gunakan untuk memastikan bahwa
this
selalu sesuai adalah untuk menetapkan variabel dalam fungsi yang sama dengan nilai yang sesuaithis
dan menggunakannya. Ini akan seperti:Sekarang, jika Anda berada dalam ruang lingkup item individu dan panggilan
$root.removeItem
, nilaithis
sebenarnya akan menjadi data yang terikat pada level tersebut (yang akan menjadi item). Dengan menggunakan diri dalam kasus ini, Anda dapat memastikan bahwa itu dihapus dari model tampilan keseluruhan.Pilihan lain adalah menggunakan
bind
, yang didukung oleh browser modern dan ditambahkan oleh KO, jika tidak didukung. Dalam hal ini, akan terlihat seperti:Ada banyak lagi yang bisa dikatakan tentang topik ini dan banyak pola yang dapat Anda jelajahi (seperti pola modul dan pola pola pengungkapan), tetapi pada dasarnya menggunakan fungsi memberi Anda lebih banyak fleksibilitas dan kontrol atas bagaimana objek dibuat dan kemampuan untuk referensi variabel yang bersifat pribadi untuk instance.
sumber
self
danthis
sama, sehingga keduanya akan sama. Dalam fungsi removeItem,self
menjadi lebih berguna, karenathis
tidak lagi menjadi instance saat ini ketika dieksekusi dalam konteks item anak.Saya menggunakan metode yang berbeda, meskipun serupa:
Beberapa alasan:
this
, yang dapat membingungkan ketika digunakan dalamko.computed
s dllnew viewModel()
)sumber
My viewModel is a singleton, I don't need to create multiple instances (i.e. new viewModel())
tetapi tidak jelas apa yang Anda coba katakan,I don't need to create multiple instances
bisakah Anda menggunakan lebih banyak sehingga orang dapat memahami manfaat dari pendekatan Anda. terima kasihfunction
adalah karena Anda akan menjalankannya lebih dari sekali. Namun, dalam contoh saya tentang, ini adalah fungsi anonim yang langsung dipanggil, sehingga tidak akan dibuat lebih dari sekali. Ini sangat mirip dengan Object Literal dalam contoh di atas, tetapi memberi Anda lebih banyak isolasi