Spec-Zone.ru › Marionette.js 3

Шаблонизация

Основное назначение представления 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
    • Функция шаблона
    • Функция getTemplate
  • Модели и коллекции
    • Отображение модели
    • Отображение коллекции
    • Взаимодействие пользователя с коллекциями
    • Правила отображения модели/коллекции
  • Контекст шаблона
    • Объект контекста
    • Привязка this
  • Сериализация данных модели и коллекции

Отображение шаблона

Выбор 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">
<h1>Hello, world</h1>
</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 использует простой метод, чтобы определить, следует ли сделать модель или коллекцию доступной для шаблона:

  1. Если view.model задано, атрибуты из model
  2. Если view.model не задано, но view.collection задано, установите items в отдельные элементы коллекции
  3. Если ни то, ни другое не задано, используется пустой объект

Результат этого смешивается в 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API