Шаблонизация
Основное назначение представления Marionette — отобразить данные вашей модели и коллекции в шаблоне, который вы ему назначили. Основной синтаксис для настройки шаблона аналогичен синтаксису представления Backbone.js template:
var Mn = require('backbone.marionette');
var _ = require('underscore');
var MyView = Mn.View.extend({
tagName: 'h1',
template: _.template('Contents')
});
var myView = new MyView();
myView.render();
Это приведет к тому, что содержимое атрибута template будет отображено внутри тега <h1>.
Индекс документации
Отображение шаблона
Выбор jQuery
Если ваша главная страница содержит элемент шаблона, отформатированный для Underscore, вы можете просто передать селектор jQuery для template и Marionette найдет его:
var Mn = require('backbone.marionette');
export.MyView = Mn.View.extend({
template: '#template-layout'
});
<script id="template-layout" type="x-template/underscore"></script>
Marionette компилирует шаблон выше, используя _.template, и отображает его, когда MyView отображается.
Функция шаблона
Более распространенный способ настройки шаблона — назначить функцию атрибуту template, которая отображает ее аргумент. Это обычно функция _.template.
var _ = require('underscore');
var Mn = require('backbone.marionette');
export.MyView = Mn.View.extend({
template: _.template('<h1>Hello, world</h1>')
});
Это не обязательно шаблон underscore, вы можете передать свою собственную функцию отображения:
var Mn = require('backbone.marionette');
var Handlebars = require('handlebars');
var MyView = Mn.View.extend({
template: function(data) {
return Handlebars.compile('<h1>Hello, {{ name }}')(data);
}
});
Использование пользовательской функции предоставляет большой контроль над выводом вашего представления после расчета его контекста. Если эта логика общая, вы можете переопределить свой рендерер, чтобы изменить ваш стандартный рендерер шаблонов.
Функция getTemplate
Функция getTemplate используется для выбора шаблона для отображения после создания представления. Вы можете использовать это, чтобы изменить шаблон на основе некоторой простой логики, например, значения определенного атрибута в модели представления. Возвращаемое значение может быть либо селектором jQuery, либо скомпилированной функцией шаблона, которая будет вызываться с данными и контекстом представления.
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
getTemplate: function(){
if (this.model.get('is_active')){
return '#template-when-active';
} else {
return '#template-when-inactive';
}
}
});
Это отличается от установки template, так как этот метод должен быть выполнен и рассчитан при отображении представления. Если ваш шаблон всегда одинаков, используйте атрибут template напрямую.
Модели и коллекции
Отображение модели
Marionette с удовольствием отобразит шаблон без модели. Это не даст нам особо интересного результата. Как и в Backbone, мы можем прикрепить модель к нашим представлениям и отобразить данные, которые они представляют:
var Bb = require('backbone');
var Mn = require('backbone.marionette');
var MyModel = Bb.Model.extend({
defaults: {
name: 'world'
}
});
var MyView = Mn.View.extend({
template: _.template('<h1>Hello, <%- name %></h1>')
});
var myView = new MyView({model: new MyModel()});
Теперь наш шаблон имеет полный доступ к атрибутам модели, переданной в представление.
Отображение коллекции
Marionette.View также предоставляет простой инструмент для отображения коллекций в шаблоне. Просто передайте коллекцию как collection и Marionette предоставит атрибут items для отображения:
var Bb = require('backbone');
var Mn = require('backbone.marionette');
var MyCollection = Bb.Collection.extend({
});
var MyView = Mn.View.extend({
template: '#hello-template'
});
var collection = new MyCollection([
{name: 'Steve'}, {name: 'Helen'}
]);
var myView = new MyView({collection: collection});
Для большей ясности мы перенесли шаблон в этот тег script:
<script id="hello-template" type="x-template/underscore">
<ul>
<% _.each(items, function(item) { %>
<li><%- item.name %></li>
<% }) %>
</ul>
</script>
Как видите, items предоставляется шаблону, представляющему каждый элемент в коллекции.
Взаимодействие пользователя с коллекциями
Хотя это возможно, реагирование на взаимодействие пользователя с отдельными элементами в вашей коллекции сложно только с View. Если вы хотите действовать на отдельных элементах, рекомендуется использовать CollectionView и обрабатывать поведение на уровне отдельных элементов.
Правила отображения модели/коллекции
Marionette использует простой метод, чтобы определить, следует ли сделать модель или коллекцию доступной для шаблона:
- Если
view.modelзадано, атрибуты изmodel - Если
view.modelне задано, ноview.collectionзадано, установитеitemsв отдельные элементы коллекции - Если ни то, ни другое не задано, используется пустой объект
Результат этого смешивается в templateContext объект и делается доступным для вашего шаблона. Использование этого означает, что вы можете настроить оболочку View, которая может действовать на collectionEvents, но отобразит свой атрибут model - если ваш model имеет атрибут items, то он всегда будет использоваться. Если вашему представлению необходимо выполнить сериализацию по другим правилам, переопределите serializeData().
Контекст шаблона
Marionette.View предоставляет атрибут templateContext, который используется для добавления дополнительной информации в ваши шаблоны. Это может быть либо объект, либо функция, возвращающая объект. Ключи в возвращаемом объекте будут смешаны с ключами модели или коллекции и станут доступными для шаблона.
Объект контекста
Используя объект контекста, просто прикрепите объект к templateContext следующим образом:
var _ = require('underscore');
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
template: _.template('<h1>Hello, <%- contextKey %></h1>'),
templateContext: {
contextKey: 'world'
}
});
var myView = new MyView();
Экземпляр myView будет отображен без ошибок, даже если у нас нет модели или коллекции — contextKey предоставляется templateContext.
Атрибут templateContext также может принимать функцию.
Функция контекста
Объект templateContext также может быть функцией, возвращающей объект. Это полезно, когда вы хотите получить доступ к информации из окружающего представления (например, к методам модели).
Чтобы использовать templateContext, просто назначьте функцию:
var _ = require('underscore');
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
template: _.template('<h1>Hello, <%- contextKey %></h1>'),
templateContext: function() {
return {
contextKey: this.getOption('contextKey')
}
}
});
var myView = new MyView({contextKey: 'world'});
Здесь мы передали параметр, к которому можно получить доступ из функции templateContext с помощью getOption(). Дополнительная информация о getOption доступна в документации по Marionette.Object.
Привязка this
При использовании функций в templateContext важно знать, что this привязано к результату serializeData() и не к представлению. Пример:
var _ = require('underscore');
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
template: _.template('<h1>Hello, <%- contextKey() %></h1>'),
templateContext: {
contextKey: function() {
return this.getOption('contextKey'); // ERROR
}
}
});
var myView = new MyView({contextKey: 'world'});
Указанный код завершится ошибкой, потому что объект контекста в шаблоне не видит представление getOption. Это также будет применяться к функциям, возвращаемым функцией templateContext, даже если сама функция привязана к контексту представления. Следующий пример должен прояснить ситуацию:
var _ = require('underscore');
var Mn = require('backbone.marionette');
var MyView = Mn.View.extend({
template: _.template('<h1>Hello, <%- contextKey() %></h1>'),
templateContext: function() {
return {
contextKeyVar: this.getOption('contextKey'), // OK - "this" refers to view
contextKeyFunction: function() {
return this.getOption('contextKey'); // ERROR - "this" refers to data
}
};
}
});
var myView = new MyView({contextKey: 'world'});
Сериализация данных модели и коллекции
Метод serializeData используется для преобразования model или collection представления в представление, пригодное для шаблона. Он следует правилам отображения модели/коллекции, чтобы определить, как сериализовать данные.
Результат serializeData включён в данные, передаваемые шаблону представления.
Давайте рассмотрим некоторые примеры работы с сериализацией данных.
var myModel = new MyModel({foo: 'bar'});
new MyView({
template: '#myItemTemplate',
model: myModel
});
MyView.render();
<script id="myItemTemplate" type="template">
Foo is: <%= foo %>
</script>
Если сериализация — коллекция, результаты передаются в виде массива items.
var myCollection = new MyCollection([{foo: 'bar'}, {foo: 'baz'}]);
new MyView({
template: '#myCollectionTemplate',
collection: myCollection
});
MyView.render();
<script id="myCollectionTemplate" type="template">
<% _.each(items, function(item){ %>
Foo is: <%= foo %>
<% }); %>
</script>
Если вам нужно сериализовать model или collection представления по-своему, переопределите либо serializeModel, либо serializeCollection.
С другой стороны, не используйте этот метод для добавления произвольных дополнительных данных в шаблон. Вместо этого используйте View.templateContext.
© 2017 Muted Solutions, LLC
Licensed under the MIT License.
https://marionettejs.com/docs/v3.5.1/template.html