Це чудове питання. Хребна хребта чудова через відсутність її припущень, але це означає, що ви повинні (вирішити, як це зробити) реалізувати подібні речі самостійно. Переглянувши власні речі, я виявив, що я (вид) використовую поєднання сценарію 1 та сценарію 2. Я не думаю, що четвертий магічний сценарій існує, тому що, достатньо просто, все, що ви робите в сценарії 1 та 2, повинно бути зроблено.
Я думаю, що було б найпростіше пояснити, як мені подобається обробляти це прикладом. Скажіть, у мене ця проста сторінка розбита на вказані представлення:

Скажіть, HTML-код після рендерингу виглядає приблизно так:
<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>
Сподіваємось, досить очевидно, як HTML відповідає діаграмі.
ParentViewМає 2 дочірні уявлення, InfoViewі PhoneListView, а також кілька додаткових діви, один з яких, #name, повинен бути встановлений в будь - то момент. PhoneListViewмістить власні подання дитини, масив PhoneViewзаписів.
Отже, до вашого актуального питання. Я обробляю ініціалізацію та рендерінг по-різному, залежно від типу перегляду. Я розбиваю свої погляди на два типи, Parentпогляди та Childпогляди.
Різниця між ними проста: Parentперегляди зберігають уявлення дітей, тоді як Childпогляди не мають. Так у моєму прикладі ParentViewі PhoneListViewє Parentпогляди, а InfoViewі PhoneViewзаписи - це Childпогляди.
Як я вже згадував раніше, найбільша різниця між цими двома категоріями полягає в тому, коли їм дозволяється показувати. У ідеальному світі я хочу, щоб Parentпогляди відображалися лише один раз. Їх дочірнє уявлення залежить від будь-якого рендерінга, коли змінюються моделі. ChildЗ іншого боку, я дозволяю повторно відображати в будь-який час, коли їм потрібно, оскільки у них немає інших поглядів, на яких вони покладаються.
Трохи докладніше, для Parentпереглядів мені подобається, щоб мої initializeфункції виконували кілька речей:
- Ініціалізую власний погляд
- Надайте власний погляд
- Створіть та ініціалізуйте будь-які дитячі представлення даних.
- Призначте кожному дочірньому перегляду елемент в моєму вікні (наприклад
InfoView, буде призначено #info).
Крок 1 досить зрозумілий.
Крок 2, візуалізація, робиться так, що будь-які елементи, на які спирається дитина, вже існують, перш ніж я спробую їх призначити. Роблячи це, я знаю, що вся дитина eventsбуде правильно встановлена, і я можу повторно відображати їх блоки стільки разів, скільки мені хочеться, не переживаючи про необхідність повторного делегування. Я фактично не бачу тут renderжодної дитини, я дозволяю їм це робити в межах власнихinitialization .
Етапи 3 та 4 фактично обробляються в той же час, коли я проходжу el під час створення дочірнього виду. Мені подобається передати тут елемент, оскільки я вважаю, що батько повинен визначити, куди, на власний погляд, дитині дозволяється розміщувати його вміст.
Що стосується візуалізації, я намагаюся тримати це досить просто для Parentперегляду. Я хочу, щоб ця renderфункція не мала нічого іншого, як відображення батьківського подання. Ні делегації подій, ні надання дитячих поглядів, нічого. Просто простий візуалізацію.
Іноді це не завжди працює. Наприклад, у моєму прикладі вище, #nameелемент потрібно буде оновлювати кожного разу, коли ім’я в моделі змінюється. Однак цей блок є частиною ParentViewшаблону і не обробляється виділеним Childвидом, тому я працюю над цим. Я створю яке - то subRenderфункція , яка тільки замінює вміст #nameелемента, а не громити весь #parentелемент. Це може здатися злому, але я дійсно виявив, що це працює краще, ніж потрібно турбуватися про повторне відтворення цілого DOM та повторне прив’язування елементів тощо. Якби я дійсно хотів зробити це чистим, я створив би новий Childвид (подібний до того InfoView), який би обробляв #nameблок.
Тепер для Childпереглядів, initializationце дуже схоже на Parentпогляди, тільки без створення будь-яких подальших Childпоглядів. Так:
- Ініціалізуйте мій погляд
- Налаштування пов'язує прослуховування будь-яких змін у моделі, яка мені цікава
- Надайте мені погляд
ChildВізуалізація перегляду також дуже проста, просто візуалізуйте та встановіть мій вміст el. Знову-таки, ніякого возитися з делегацією чи чогось подібного.
Ось приклад коду того, як ParentViewможе виглядати моє :
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);
}
});
Ви можете побачити мою реалізацію subRenderтут. Зв'язавши зміни subRenderзамість render, я не повинен турбуватися про вибух і відновлення цілого блоку.
Ось приклад коду для InfoViewблоку:
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());
}
});
Тут є важлива частина палітур. Прив’язуючись до своєї моделі, мені ніколи не потрібно турбуватися про те, щоб вручну дзвонити renderсобі. Якщо модель зміниться, цей блок повторно відобразиться, не впливаючи на інші види.
PhoneListViewБуде схожий на ParentView, вам просто потрібно трохи більше логіки в обох ваших initializationі renderфункцій в колекції ручок. Як ви обробляєте колекцію, насправді залежить від вас, але вам потрібно, принаймні, слухати події колекції та вирішувати, як ви хочете візуалізувати (додати / вилучити або просто повторно відредагувати весь блок). Мені особисто подобається додавати нові перегляди та видаляти старі, а не повторювати весь перегляд.
PhoneViewБуде майже ідентичний InfoView, тільки прислухаючись до моделі змін , які вона піклується про.
Сподіваємось, це трохи допомогло, будь ласка, повідомте мене, якщо щось є заплутаним чи недостатньо детальним.