Marionette.ItemView
Класс ItemView
является представлением, которое отображает одиночный элемент,
который можно быть как Backbone.Model
, так и Backbone.Collection
.
Так или иначе, этот элемент будет рассматриваться как одиночный.
Класс ItemView
наследован напрямую от класса Marionette.View
.
Для более полной информации о доступных функциях и функциональности ознакомьтесь с документацией по Marionette.View.
Кроме того, совместное использование ItemView
с Marionette.Region
позволяет использовать такие функции как коллбэк onShow
и т.д.
Более полную информацию о классе Marionette.Region
можно найти в соответствующем разделе документации.
Содержание
- Метод
render
- Отрисовка коллекций в ItemView
- Безшаблонный ItemView
- События и Коллбеки
- Метод
serializeData
- Организация элементов UI
- События модели и коллекции
Метод render
В отличие от Backbone.Views
, все представления в Marionette обладают методом render
.
Фактически, основные различия между представлениями являются различия в их методах render
.
Очевидно, что переопределение метода render
у любого представления является неразумным. Вместо этого, вы должны
использовать onBeforeRender
и onRender
коллбеки
для добавления дополнительной функциональности в процесс отрисовки вашего представления.
ItemView
передает объекту Marionette.Renderer
сделать фактическую отрисовку шаблона.
Экземпляр ItemView
передается как третий аргумент в метод render
объекта Marionette.Renderer
. Этот аргумент может быть полезен при
собстенной реализации Marionette.Renderer
.
Вы должны определить атрибут template
в ItemView
. Этот атрибут
может быть либо JQuery-селектором:
var MyView = Marionette.ItemView.extend({
template: "#some-template"
});
new MyView().render();
.. либо финкцией, принимающей один аргумент: объект, возвращаемый ItemView.serializeData:
var myTemplateHtml = '<div><%= args.name %></div>';
var MyView = Marionette.ItemView.extend({
template : function(serialized_model) {
var name = serializedModel.name;
return _.template(myTemplateHtml)({
name : name,
someCustomAttribute : someCustomKey
});
}
});
new MyView().render();
Обратите внимание, что использование template
в виде функции позволяет
передавать собственные аргументы в функцию _.template
и позволяет
получить больший контроль над процессом вызова функции _.template
.
Более подробную информацию о функции _.template
можно узнать в документации по Underscore.
Отрисовка коллекций в ItemView
Самым часто используемым способом отрисовки Backbone.Collection
является использование CollectionView
или CompositeView
. Но иногда нужно отобразить
простой список, которому не требуется много интерактивности,
в этом случае нет смысла в использовании этих представлений. Backbone.Collection
может быть отрисована с помощью простого ItemView
. Для этого в шаблонах
можно использовать массив items
для перебора элементов коллекции.
<script id="some-template" type="text/html">
<ul>
<% _.each(items, function(item){ %>
<li> <%= item.someAttribute %> </li>
<% }); %>
</ul>
</script>
Здесь важно отметить, что items
используется как переменная для перебора (итерирования)
в вызове _.each
. В переменной items
будут всегда содержаться элементы вашей коллекции.
Таким образом, в JavaScript вы можете определить и использовать
ItemView
с шаблоном из примера выше, следующим образом:
var MyItemsView = Marionette.ItemView.extend({
template: "#some-template"
});
var view = new MyItemsView({
collection: someCollection
});
// отобразить представление, используя регион, или вызвать метод .render у представления
При отрисовки этого представления коллекция someCollection
будет преобразована
в массив items
для использования его в шаблоне.
Для получения дополнительной информации о том, когда вам может понадобится использовать такой подход,
какие параметры вы имеете для получения отдельного элемента, когда происходит событие click
или другое взаимодействие с отдельным элементом, вы можете прочитать в статье
Получение модели при клике на элемент.
Безшаблонный ItemView
ItemView
можно без особых проблем связать с существующими элементам. Основное приемущество этого заключается в
возможности добавить поведение или события к статическому контенту, который был отрисован на сервере
(как правило, для целей SEO). Что бы создать безшаблонный ItemView
, вам нужно установить
атрибуту template
значение false
.
<div id="my-element">
<p>Hello World</p>
<button class="my-button">Click Me</button>
</div>
var MyView = Marionette.ItemView.extend({
el: '#my-element',
template: false,
ui: {
paragraph: 'p',
button: '.my-button'
},
events: {
'click @ui.button': 'clickedButton'
},
clickedButton: function() {
console.log('I clicked the button!');
}
});
var view = new MyView();
view.render();
view.ui.paragraph.text(); // возвращает 'Hello World'
view.ui.button.trigger('click'); // в логе будет сообщение 'I clicked the button!'
Другой вариант использования, это когда вы хотите связать Marionette.ItemView
с SVG-графикой или
canvas-элементом, для создания единого интерфейса в виде слоя представления к нестандартным DOM-узлам.
ItemView
без шаблона позволяет вам также использовать представление для предварительно отрисованных
DOM-узлов, таких как сложные грфические элементы.
События и Коллбеки
Есть несколько событий и коллбеков, которые вызываются у ItemView
.
Эти события/коллбеки инициируются/вызываются с помощью функции
Marionette.triggerMethod,
которая инициирует событие и вызывает соответствующий метод “on{ИмяСобытия}”.
событие before:render
/ коллбек onBeforeRender
Инициируется до того, как ItemView
будет отрисовано.
Marionette.ItemView.extend({
onBeforeRender: function(){
// последние действия перед тем, как сгенерируется `el` представления
}
});
событие render
/ коллбек onRender
Инициируется после того, как представление было отрисовано.
Вы можете сами реализовать этот метод в вашем представлении
для того, чтобы добавить собственный код для работы с el
представления
после того, как el
было сгенерировано.
Marionette.ItemView.extend({
onRender: function(){
// здесь манипулируем `el`. Оно уже было сгенерировано и
// содержит готовый для работы HTML представления.
}
});
событие before:destroy
/ коллбек onBeforeDestroy
Инициируется только перед тем, как представление будет уничтожено, в момент,
когда метод destroy()
представление был вызван.
Marionette.ItemView.extend({
onBeforeDestroy: function(){
// здесь манипулируем `el`. Оно уже было сгенерировано и
// содержит готовый для работы HTML представления.
}
});
событие destroy
/ коллбек onDestroy
Инициируется только после того, как предствление было уничтожено.
Marionette.ItemView.extend({
onDestroy: function(){
// здесь размещается собственный код для уничтожения и очистки
}
});
Метод serializeData
ItemView
будет сериализовывать модель или коллекцию. По умолчанию, вызывается
метод .toJSON
у модели или коллекции. Если ItemView
содержит одновременно
модель и коллекцию, то только модель будет использоваться как источник данных для представления.
Результат сериализации будет передан в шаблон, который отрисовывается.
Если сериализуется модель, то результат сериализации передается непосредственно:
var myModel = new MyModel({foo: "bar"});
new MyItemView({
template: "#myItemTemplate",
model: myModel
});
MyItemView.render();
<script id="myItemTemplate" type="template">
Foo is: <%= foo %>
</script>
Если сериализуется коллекция, то результат сериализации передается в виде массива items
:
var myCollection = new MyCollection([{foo: "bar"}, {foo: "baz"}]);
new MyItemView({
template: "#myCollectionTemplate",
collection: myCollection
});
MyItemView.render();
<script id="myCollectionTemplate" type="template">
<% _.each(items, function(item){ %>
Foo is: <%= foo %>
<% }); %>
</script>
Если вам нужен собственный способ сериализации ваших данных,
то вы можете переопределить метод serializeData
в вашем представлении.
Метод должен возвращать корректный JSON-объект, как если бы вы вызвали метод
.toJSON
у модели или коллекции.
Marionette.ItemView.extend({
serializeData: function(){
return {
"some attribute": "some value"
}
}
});
Организация элементов UI
Как говорилось в документации по Marionette.View, вы можете
указать хеш ui
в вашем представлении. В хеше ui
сопоставляются
элементы UI с их jQuery-селекторами. Это особенно полезно, если вы хотите получать доступ
к одному и тому же UI элементу несколько раз в вашем коде. Вместо того, чтобы дублировать селектор,
вы можете просто ссылаться на него при помощи this.ui.elementName
.
Вы можете также использовать значения хеша ui
в ключах хешей events
и trigger
,
используя следующий синтакс: "@ui.elementName"
Marionette.ItemView.extend({
tagName: "tr",
ui: {
checkbox: "input[type=checkbox]"
},
onRender: function() {
if (this.model.get('selected')) {
this.ui.checkbox.addClass('checked');
}
}
});
События модели и коллекции
ItemView
может напрямую осуществлять привязку к событиям модели и событиям коллекции,
используя для этого хеши modelEvents
и collectionEvents
соответственно:
Marionette.ItemView.extend({
modelEvents: {
"change": "modelChanged"
},
collectionEvents: {
"add": "modelAdded"
}
});
Больше информации можно прочитать в документации по Marionette.View.