Ini pertanyaan yang bagus. Backbone bagus karena kurangnya asumsi yang dibuatnya, tetapi itu berarti Anda harus (memutuskan bagaimana) mengimplementasikan hal-hal seperti ini sendiri. Setelah melihat-lihat barang saya sendiri, saya menemukan bahwa saya (jenis) menggunakan campuran skenario 1 dan skenario 2. Saya tidak berpikir skenario ajaib ke-4 ada karena, cukup sederhana, semua yang Anda lakukan dalam skenario 1 & 2 harus selesai
Saya pikir akan lebih mudah untuk menjelaskan bagaimana saya ingin menanganinya dengan sebuah contoh. Katakanlah saya memiliki halaman sederhana ini dipecah menjadi tampilan yang ditentukan:
Katakan HTML, setelah dirender, kira-kira seperti ini:
<div id="parent">
<div id="name">Person: Kevin Peel</div>
<div id="info">
First name: <span class="first_name">Kevin</span><br />
Last name: <span class="last_name">Peel</span><br />
</div>
<div>Phone Numbers:</div>
<div id="phone_numbers">
<div>#1: 123-456-7890</div>
<div>#2: 456-789-0123</div>
</div>
</div>
Semoga cukup jelas bagaimana HTML cocok dengan diagram.
The ParentView
memegang 2 pandangan anak, InfoView
dan PhoneListView
juga beberapa div tambahan, salah satunya #name
, perlu diatur di beberapa titik. PhoneListView
memiliki pandangan anak sendiri, sebuah array PhoneView
entri.
Demikian pertanyaan Anda yang sebenarnya. Saya menangani inisialisasi dan rendering berbeda berdasarkan tipe tampilan. Saya memecah pandangan saya menjadi dua jenis, Parent
pandangan dan Child
pandangan.
Perbedaan di antara mereka sederhana, Parent
pandangan menahan pandangan anak sementara Child
pandangan tidak. Jadi, dalam contoh saya, ParentView
dan PhoneListView
yang Parent
dilihat, sementara InfoView
dan PhoneView
entri Child
pandangan.
Seperti yang saya sebutkan sebelumnya, perbedaan terbesar antara kedua kategori ini adalah ketika mereka diizinkan untuk membuat. Di dunia yang sempurna, saya ingin Parent
pandangan hanya ditampilkan sekali. Terserah pandangan anak mereka untuk menangani rendering ulang ketika model berubah. Child
di sisi lain, saya mengizinkan untuk merender ulang kapan pun mereka butuhkan karena mereka tidak memiliki pandangan lain yang mengandalkannya.
Secara lebih rinci, untuk Parent
tampilan saya suka initialize
fungsi saya untuk melakukan beberapa hal:
- Inisialisasi pandangan saya sendiri
- Jadikan pandangan saya sendiri
- Buat dan inisialisasi pandangan anak apa saja.
- Tetapkan setiap anak untuk melihat elemen dalam tampilan saya (mis. Yang
InfoView
akan ditugaskan #info
).
Langkah 1 cukup jelas.
Langkah 2, rendering, dilakukan agar setiap elemen yang dilihat anak mengandalkan sudah ada sebelum saya mencoba untuk menetapkannya. Dengan melakukan ini, saya tahu semua anak events
akan diatur dengan benar, dan saya dapat merender ulang blok mereka sebanyak yang saya inginkan tanpa khawatir harus mendelegasikan ulang apa pun. Saya tidak benar render
- benar melihat anak di sini, saya membiarkan mereka melakukan itu di dalam mereka sendiri initialization
.
Langkah 3 dan 4 sebenarnya ditangani pada saat yang sama ketika saya masuk el
sambil membuat tampilan anak. Saya suka melewatkan elemen di sini karena saya merasa orang tua harus menentukan di mana dalam pandangannya sendiri anak diizinkan untuk meletakkan kontennya.
Untuk rendering, saya mencoba membuatnya tetap sederhana untuk Parent
dilihat. Saya ingin render
fungsi tidak lebih dari membuat tampilan induk. Tidak ada delegasi acara, tidak ada rendering tampilan anak, tidak ada. Hanya membuat sederhana.
Kadang-kadang ini tidak selalu berhasil. Misalnya dalam contoh saya di atas, #name
elemen harus diperbarui setiap kali nama dalam model berubah. Namun, blok ini adalah bagian dari ParentView
template dan tidak ditangani oleh tampilan khusus Child
, jadi saya mengatasinya. Saya akan membuat semacam subRender
fungsi yang hanya menggantikan konten #name
elemen, dan tidak harus membuang seluruh #parent
elemen. Ini mungkin tampak seperti peretasan, tapi saya benar-benar menemukan itu bekerja lebih baik daripada harus khawatir tentang rendering ulang seluruh DOM dan elemen-elemen pemasangan kembali dan semacamnya. Jika saya benar-benar ingin membuatnya bersih, saya akan membuat tampilan baru Child
(mirip dengan InfoView
) yang akan menangani #name
blok.
Sekarang untuk Child
tampilan, initialization
sangat mirip dengan Parent
tampilan, hanya tanpa penciptaan Child
tampilan lebih lanjut . Begitu:
- Inisialisasi pandangan saya
- Setup mengikat mendengarkan untuk setiap perubahan pada model yang saya pedulikan
- Jadikan pandangan saya
Child
rendering tampilan juga sangat sederhana, cukup render dan atur konten saya el
. Sekali lagi, jangan main-main dengan delegasi atau semacamnya.
Berikut ini beberapa contoh kode ParentView
tampilan saya :
var ParentView = Backbone.View.extend({
el: "#parent",
initialize: function() {
// Step 1, (init) I want to know anytime the name changes
this.model.bind("change:first_name", this.subRender, this);
this.model.bind("change:last_name", this.subRender, this);
// Step 2, render my own view
this.render();
// Step 3/4, create the children and assign elements
this.infoView = new InfoView({el: "#info", model: this.model});
this.phoneListView = new PhoneListView({el: "#phone_numbers", model: this.model});
},
render: function() {
// Render my template
this.$el.html(this.template());
// Render the name
this.subRender();
},
subRender: function() {
// Set our name block and only our name block
$("#name").html("Person: " + this.model.first_name + " " + this.model.last_name);
}
});
Anda dapat melihat implementasi saya di subRender
sini. Dengan memiliki perubahan yang terikat subRender
alih-alih render
, saya tidak perlu khawatir tentang peledakan dan membangun kembali seluruh blok.
Berikut contoh kode untuk InfoView
blok:
var InfoView = Backbone.View.extend({
initialize: function() {
// I want to re-render on changes
this.model.bind("change", this.render, this);
// Render
this.render();
},
render: function() {
// Just render my template
this.$el.html(this.template());
}
});
Ikatan adalah bagian penting di sini. Dengan mengikat ke model saya, saya tidak perlu khawatir menyebut render
diri saya secara manual . Jika model berubah, blok ini akan merender ulang sendiri tanpa memengaruhi tampilan lainnya.
The PhoneListView
akan mirip dengan ParentView
, Anda hanya perlu logika sedikit lebih baik Anda initialization
dan render
fungsi untuk menangani koleksi. Cara Anda menangani koleksi benar-benar terserah Anda, tetapi Anda setidaknya harus mendengarkan acara pengumpulan dan memutuskan bagaimana Anda ingin me-render (menambahkan / menghapus, atau hanya me-render ulang seluruh blok). Saya pribadi ingin menambahkan tampilan baru dan menghapus yang lama, bukan membuat ulang seluruh tampilan.
The PhoneView
akan hampir identik dengan InfoView
, hanya mendengarkan perubahan model itu peduli.
Semoga ini sedikit membantu, tolong beri tahu saya jika ada sesuatu yang membingungkan atau tidak cukup detail.