Це чудове питання. Хребна хребта чудова через відсутність її припущень, але це означає, що ви повинні (вирішити, як це зробити) реалізувати подібні речі самостійно. Переглянувши власні речі, я виявив, що я (вид) використовую поєднання сценарію 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
, тільки прислухаючись до моделі змін , які вона піклується про.
Сподіваємось, це трохи допомогло, будь ласка, повідомте мене, якщо щось є заплутаним чи недостатньо детальним.