Marionette.CompositeView
CompositeView
расширяет CollectionView
и обычно используется в сценариях где нужно отразить “ветвь и листья”, или
в сценариях, где коллекцию нужно вставить в “оборачивающий” ее шаблон.
По умолчанию, CompositeView
отражает сортировку коллекции в DOM.
Такое поведение можно отключить, определяя {sort: false}
при инициализации.
Подробнее the Marionette.CollectionView documentation
Дополнительно, взаимодействие с Marionette.Region
даст возможность использовать различные кэллбеки, например onShow
.
Подробнее the Region documentation.
Пример: Tree View
Для примера, вы рендерите древовидное представление. Возможно, вы хотите рендерить collection view с моделью и шаблоном. Именно для ренедринга более сложных представлений ( чем просто список колеекции) и служит CompositeView.
Вы можете определить modelView
для использования в отрисовке каждой модели. Если не определяете, будет использоваться
дефолтный Marionette.ItemView
.
var CompositeView = Marionette.CompositeView.extend({
template: "#leaf-branch-template" // шаблон всего представления
});
new CompositeView({
model: someModel,
collection: someCollection
});
Дополнительные примеры using the composite view.
Содержание
- Composite Model
template
- CompositeView’s
childView
- CompositeView’s
childViewContainer
- CompositeView’s
attachHtml
- Recursive By Default
- Model And Collection Rendering
- Events And Callbacks
- Organizing UI elements
- modelEvents and collectionEvents
Composite Model template
Когда CompositeView
рендерится, каждая model
будет рендериться с шаблоном template
определенным в ее ( модели)
представлении. Вы можете переопределить шаблон для CompositeView
, передавая его конструктору в опциях.
new MyComp({
template: "#some-template" // шаблон CompositeView
});
Опция collection
не передается в контекст шаблона по умолчанию. Если в шаблоне требуется доступ к коллекции,
вам нужно будет передавать ее используя templateHelpers
.
new MyComp({
template: "#some-template",
templateHelpers: function() {
return { items: this.collection.toJSON() };
}
})
CompositeView’s childView
Каждый childView
будет рендерится используя класс описанный в childView
опции. Сначала отрисуется CompositeView
шаблон,
после этого, добавятся дети с childView
шаблонами.
var ChildView = Marionette.ItemView.extend({});
var CompView = Marionette.CompositeView.extend({
childView: ChildView
});
CompositeView’s childViewContainer
По умолчанию, CompositeView
использует attachHtml
метод из СollectionView
. Это означает,
что представление будет вызывать jQuery метод append
для размещения HTML содержимого из вложенных childView
инстансов
в collectionView
el
.
Скорее всего, это не очень соответствует вашим задачам рендеринга кажого вложенного представления в необходимое место.
Например, если вы строите табличное представление, и хотите прибавлять каждого ребенка из коллекции в <tbody>
таблицы.
Вероятно, вы будете использовать следующий шаблон.
<script id="row-template" type="text/html">
<td><%= someData %></td>
<td><%= moreData %></td>
<td><%= stuff %></td>
</script>
<script id="table-template" type="text/html">
<table>
<thead>
<tr>
<th>Some Column</th>
<th>Another Column</th>
<th>Still More</th>
</tr>
</thead>
<!-- хотим вставить отображение коллекции в это место -->
<tbody></tbody>
<tfoot>
<tr>
<td colspan="3">some footer information</td>
</tr>
</tfoot>
</table>
</script>
Для рендеринга ваших childView
инстансов внутри <tbody>
, определите childViewContainer
в вашем CompositeView
.
var RowView = Marionette.ItemView.extend({
tagName: "tr",
template: "#row-template"
});
var TableView = Marionette.CompositeView.extend({
childView: RowView,
// определяем jQuery селектор, внутрь которого будем добавлять `childView` инстансы
childViewContainer: "tbody",
template: "#table-template"
});
Это разместит все childView
инстасы внутри <tbody>
тега родительского шаблона и корректно отрисует
структуру таблицы ( в данном примере).
Или вы можете определить функцию для опции childViewContainer
. Функции необходиом возвращать jQuery селектор, или
jQuery объект.
var TableView = Marionette.CompositeView.extend({
// ...
childViewContainer: function(){
return "#my-tbody"
}
});
Использование функции, позволяет добавить логику для возвората определенного селектора. Однако, только одно значение может быть возвращено. Первое возвращаемое значение будет закешированно, и будет использоваться в весь период работы представления.
Также, childViewContainer
можно передать в конструкторе класса.
var myComp = new Marionette.CompositeView({
// ...,
childViewContainer: "#my-tbody"
});
CompositeView’s attachHtml
Иногда, конфигурация childViewContainer
недостаточна для специфического размещения “определенных” childView
представлений.
В этом случае, можно переопределить attachHtml
метод.
Подробнее смотреть тут CollectionView’s documentation.
CompositeView’s childView
выбор контейнера
Метод getChildViewContainer
получает вторым параметром childView
, который, если переопределен, позволит выбирать
“специфический” контейнер (containerView
возвращаемый методом getChildViewContainer
) для размещения детей.
Recursive по умолчанию
Режим рендеринга CompositeView
предполагает (допускает) иерархическую, рекурсивную структуру данных. Если вы
не определяете какой либо childView
для вашего CompositeView
, то дети будут отрендерены одним и тем же
методом рендеринга класса CompositeView
.
Model и Collection ререндеринг
Модель и коллекция для CompositeView
будет перерисовываться при следующих условиях.
- Когда в коллекции происходит событие “reset”. Перерендерится только коллекция внутри
Composite
, окружающий шаблон не затрагивается. - При добавлении модели в коллекцию (событие “add”), отрендерится только один ребенок в списке.
- Удаление модели из коллекции (событие “remove”), удалит только одного ребенка из уже отрисованного списка
Как и в ItemView
, CompositeView
получает третьим аргументом Renderer
объект render
метода, удобный для
кастомной реализации своего Renderer
-а.
События и кэлбеки
При рендеринге compositeView
будет вызванно несколько событий. События триггерятся с помощью
Marionette.triggerMethod функции, которая вызывает соответствующие
on{EventName}
методы представления.
- “before:render:template” /
onBeforeRenderTemplate
- перед рендерингомmodel
- “render:template” /
onRenderTemplate
- после рендерингаmodel
- “before:render:collection” /
onBeforeRenderCollection
- перед рендеригом коллекции моделей - “render:collection” /
onRenderCollection
- после рендеринга коллекция моделей - “before:render” /
onBeforeRender
- перед тем, как что нибудь будет отрендерено - “render” /
onRender
- после того, как что либо будет рендерится
Кроме этого, после ренедринга CompositeView
, будет вызван метод onRender
. Вы можете определить этот метод
в вашем представлении, и ваш код сможет работать с el
представления, после его (представления) “полного” рендеринга.
Marionette.CompositeView.extend({
onRender: function(){
// Шаблон compositeView и вложенная коллекция уже отрендерены, через this.el поимеем к ним доступ
}
});
Организация UI элементов
Аналогично с ItemView
, вы можете описать UI элементы внутри CompositeView
используя UI
хеш. Заметим, что элементы
из этого хеша, это элементы, отрендериваемые CompositeView
шаблоном , а не вложенными.
UI элементы будут доступны, как только шаблон CompositeView
отрендерится (но перед рендерингом коллекции), т.е. вы сможете
иметь к UI элементам доступ в методе onBeforeRender
.
События модели и коллекции
CompositeViews
может связываться напрямую к событиям модели и коллекции в декларативном виде при определении класса.
Marionette.CompositeView.extend({
modelEvents: {
"change": "modelChanged"
},
collectionEvents: {
"add": "modelAdded"
}
});
Подробнее смотреть Marionette.View