Marionette.LayoutView
A LayoutView является гибридом ItemView и коллекции Region объектов. Они идеально подходят для отрисовки макетов приложений с несколькими подобластями, управляемыми указанными менеджерами областей.
LayoutView также может действовать как компонентный вид для агрегирования нескольких представлений и подприложений экрана, позволяя приложениям подключать несколько менеджеров областей к динамически отрисовываемому HTML.
Вы можете создавать сложные представления, вложенные менеджеры LayoutView в Regions.
Для более глубокого обсуждения LayoutView см. статью в блоге Manage Layouts And Nested Views With Marionette
Для получения дополнительной информации об имеющихся функциях и возможностях см. документацию Marionette.ItemView по адресу marionette.itemview.
Кроме того, взаимодействия с Marionette.Region обеспечат такие функции, как onShow обратные вызовы и т. д. Для получения дополнительной информации см. документацию по регионам по адресу регионам.
Индекс документации
- Базовое использование
- Параметры области
- LayoutView.childEvents
- Определение областей как функции
- Переопределение стандартного RegionManager
- Доступность области
- Повторная отрисовка LayoutView
- Вложенные LayoutView и представления
- Удаление LayoutView
- Пользовательский класс Region
- Добавление и удаление областей
- Именование областей
Базовое использование
LayoutView непосредственно наследуется от ItemView и добавляет возможность указания regions, которые становятся экземплярами Region, прикреплёнными к LayoutView.
<script id="layout-view-template" type="text/template">
<section>
<navigation id="menu">...</navigation>
<article id="content">...</article>
</section>
</script>
var AppLayoutView = Marionette.LayoutView.extend({
template: "#layout-view-template",
regions: {
menu: "#menu",
content: "#content"
}
});
var layoutView = new AppLayoutView();
layoutView.render();
После отрисовки LayoutView у вас есть прямой доступ ко всем указанным областям в качестве менеджеров областей.
layoutView.getRegion('menu').show(new MenuView(), options);
layoutView.getRegion('content').show(new MainContentView(), options);
Также существуют полезные сокращения для более краткого синтаксиса.
layoutView.showChildView('menu', new MenuView(), options);
layoutView.showChildView('content', new MainContentView(), options);
Параметры области
LayoutView может принимать regions хеш, позволяющий указывать области для каждого экземпляра LayoutView.
new Marionette.LayoutView({
regions: {
"cat": ".doge",
"wow": {
selector: ".such",
regionClass: Coin
}
}
})
LayoutView childEvents
Хеш или метод childEvents позволяют обрабатывать события дочерних представлений без ручного задания привязок. Значения хеша могут быть функцией или именем метода в представлении коллекции.
// childEvents can be specified as a hash...
var MyLayoutView = Marionette.LayoutView.extend({
childEvents: {
// This callback will be called whenever a child is rendered or emits a `render` event
render: function() {
console.log('A child view has been rendered.');
}
}
});
// ...or as a function that returns a hash.
var MyLayoutView = Marionette.LayoutView.extend({
childEvents: function() {
return {
render: this.onChildRendered
}
},
onChildRendered: function () {
console.log('A child view has been rendered.');
}
});
childEvents также перехватывает пользовательские события, генерируемые дочерним представлением. Обратите внимание, что первым аргументом обработчика childEvents является само дочернее представление. Предупреждение: события, сгенерированные в дочернем представлении с помощью this.trigger, пока не поддерживаются для LayoutView childEvents. Используйте строго triggerMethod в дочернем представлении.
// The child view fires a custom event, `show:message`
var ChildView = Marionette.ItemView.extend({
// Events hash defines local event handlers that in turn may call `triggerMethod`.
events: {
'click .button': 'onClickButton'
},
// Triggers hash converts DOM events directly to view events catchable on the parent.
triggers: {
'submit form': 'submit:form'
},
onClickButton: function () {
this.triggerMethod('show:message', 'foo');
}
});
// The parent uses childEvents to catch that custom event on the child view
var ParentView = Marionette.LayoutView.extend({
childEvents: {
'show:message': 'onChildShowMessage',
'submit:form': 'onChildSubmitForm'
},
onChildShowMessage: function (childView, message) {
console.log('A child view fired show:message with ' + message);
},
// Methods called from the triggers hash do not have access to DOM events
// Any logic requiring the original DOM event should be handled in it's respective view
onChildSubmitForm: function (childView) {
console.log('A child view fired submit:form');
}
});
Определение областей как функции
Области могут быть определены в LayoutView с помощью функции, возвращающей объект с определениями областей. Возвращаемый объект следует тем же правилам определения области, что и указанные выше.
Marionette.LayoutView.extend({
// ...
regions: function(options){
return {
fooRegion: "#foo-element"
};
},
// ...
});
Обратите внимание, что функция получает options аргументы представления, переданные в конструктор представления. this.options ещё недоступны при первом инициализации областей, поэтому к параметрам необходимо обращаться через этот параметр.
Переопределение стандартного RegionManager
Если вам нужен класс RegionManager , выбранный динамически, укажите getRegionManager:
Marionette.LayoutView.extend({
// ...
getRegionManager: function() {
// custom logic
return new MyRegionManager();
}
Это может быть полезно, если вы хотите прикрепить области LayoutView к своему экземпляру RegionManager.
Доступность области
Все определенные области в LayoutView будут доступны для представления или любого вызывающего кода сразу после создания представления. Это позволяет прикрепить представление к существующему элементу DOM в HTML-странице без необходимости вызывать метод рендеринга или что-либо ещё для создания областей.
Однако область сможет заполнить себя только в том случае, если у представления есть доступ к элементам, указанным в определениях области. То есть, если ваше представление ещё не отрисовано, ваши области, возможно, не смогут найти элемент, который вы указали для их управления. В этом случае использование области не приведет к изменениям в DOM.
Повторная отрисовка LayoutView
LayoutView можно отрисовывать многократно, но отрисовки после первой ведут себя иначе, чем начальная отрисовка.
При первой отрисовке LayoutView ничего особенного не происходит. Он просто делегирует отрисовку методу прототипа ItemView. Однако после первой отрисовки функция рендеринга модифицируется для учёта повторной отрисовки с областями в LayoutView.
После первой отрисовки все последующие отрисовки будут очищать каждую область, вызывая метод empty для каждой из них. Это приведёт к уничтожению каждого представления в области и всех вложенных представлений, если таковые имеются. После очистки области также будут сброшены, так что они больше не будут ссылаться на элемент предыдущей отрисовки LayoutView.
Затем, после завершения повторной отрисовки LayoutView, показ представления в областях LayoutView приведет к прикреплению областей к новым элементам в LayoutView.
Избегайте повторной отрисовки всего LayoutView
Иногда требуется перерисовать весь LayoutView. Однако из-за описанного выше поведения это может потребовать больших усилий для полного восстановления LayoutView и всех представлений, отображаемых LayoutView.
Поэтому рекомендуется избегать повторной отрисовки всего LayoutView, если это не абсолютно необходимо. Вместо этого, если вы привязываете шаблон LayoutView к модели и вам нужно обновить части LayoutView, вы должны прослушивать события «изменения» модели и обновлять только необходимые элементы DOM.
Вложенные LayoutViews и представления
Так как LayoutView напрямую наследуется от ItemView, он имеет все основные функциональные возможности представления элемента. Это включает методы, необходимые для отображения внутри существующего менеджера области.
В следующем примере мы будем использовать области приложения в качестве основы глубоко вложенной структуры представления.
// Create an Application
var MyApp = new Marionette.Application();
// Add a region
MyApp.addRegions({
main: "main"
});
// Create a new LayoutView
var layoutView = new Marionette.LayoutView({
// This option removes the layoutView from
// the DOM before destroying the children
// preventing repaints as each option is removed.
// However, it makes it difficult to do close animations
// for a child view (false by default)
destroyImmediate: true
});
// Lastly, show the LayoutView in the App's mainRegion
MyApp.rootView.getRegion('main').show(layoutView, options);
Вы можете вкладывать LayoutView на любую глубину. Это обеспечивает хорошо организованную вложенную структуру представлений.
Например, чтобы вложить 3 макета:
var layout1 = new Layout1();
var layout2 = new Layout2();
var layout3 = new Layout3();
MyApp.rootView.getRegion('main').show(layout1, options);
layout1.showChildView('region1', layout2);
layout2.showChildView('region2', layout3);
Эффективные вложенные структуры представлений
Приведённый выше пример отлично работает, но он вызывает три отдельных отрисовки: по одной для каждого макета, который отображается. Marionette предоставляет простой механизм для бесконечного вложения представлений в одну отрисовку: просто отрисуйте все дочерние элементы в onBeforeShow обратном вызове.
var ParentLayout = Marionette.LayoutView.extend({
onBeforeShow: function() {
this.showChildView('header', new HeaderView());
this.showChildView('footer', new FooterView());
}
});
myRegion.show(new ParentLayout(), options);
В этом примере двухуровневая вложенная структура представления будет отрисована в одной отрисовке.
Эта система рекурсивна, поэтому она работает с любой глубоко вложенной структурой. Дочерние представления, которые вы показываете, могут отрисовывать свои дочерние представления в своих onBeforeShow обратных вызовах!
Использование события attach
Часто вам нужно знать, когда ваши представления в дереве представлений были прикреплены к document, например, при использовании определённых плагинов jQuery. Событие attach и связанный с ним onAttach обратный вызов идеально подходят для этой задачи. Начните с области, являющейся дочерним элементом document и покажите любой LayoutView в нём: каждое представление в дереве (включая родительский LayoutView) получит событие attach при прикреплении к document.
Обратите внимание, что неэффективная отрисовка дерева может привести к тому, что событие attach будет срабатывать несколько раз. Такая ситуация может возникнуть, если вы отрисовываете дочерние представления после отрисовки родительского, например, с использованием onShow для отрисовки дочерних элементов. Как правило, в большинстве случаев вы захотите отрисовать любые вложенные представления в обратном вызове onBeforeShow.
Удаление LayoutView
Когда вы закончите с LayoutView, вы можете вызвать метод destroy для него. Это гарантирует, что все менеджеры областей внутри LayoutView будут удалены правильно, что, в свою очередь, гарантирует правильное удаление всех представлений, отображаемых в областях.
Если вы показываете LayoutView внутри родительского менеджера области, замена LayoutView другим представлением или другим LayoutView приведёт к удалению текущего, так же как и удаление представления.
Всё это гарантирует, что LayoutView и представления, которые они содержат, будут корректно удалены.
Вызов destroy для LayoutView вернёт его. Это может быть полезно для цепочки вызовов.
Пользовательский класс Region
Если вам нужно заменить Region на свой собственный класс региона, вы можете указать альтернативный класс с помощью свойства regionClass для LayoutView.
var MyLayoutView = Marionette.LayoutView.extend({
regionClass: SomeCustomRegion
});
Вы также можете указать пользовательские классы Region для каждой region:
var AppLayoutView = Marionette.LayoutView.extend({
template: "#layout-view-template",
regionClass: SomeDefaultCustomRegion,
regions: {
menu: {
selector: "#menu",
regionClass: CustomRegionClassReference
},
content: {
selector: "#content",
regionClass: CustomRegionClass2Reference
}
}
});
Добавление и удаление областей
Области могут добавляться и удаляться по мере необходимости в экземпляре LayoutView. Используйте следующие методы:
addRegionaddRegionsremoveRegion
addRegion:
var layoutView = new MyLayoutView();
// ...
layoutView.addRegion("foo", "#foo");
layoutView.getRegion('foo').show(new someView(), options);
addRegions:
var layoutView = new MyLayoutView();
// ...
// Object literal
layoutView.addRegions({
foo: "#foo",
bar: "#bar"
});
// Or, function that returns an object literal
layoutView.addRegions(function() {
return {
baz: "#baz",
quux: "#quux"
};
});
removeRegions:
var layoutView = new MyLayoutView();
// ...
layoutView.removeRegion("foo");
Любая область может быть удалена, независимо от того, была ли она определена в атрибуте regions определения области или добавлена позже.
Для получения дополнительной информации об использовании этих методов см. документацию regionManager.
Именование областей
Области LayoutView прикрепляются непосредственно к экземпляру LayoutView с именем области в качестве ключа и самой областью в качестве значения. Поэтому необходимо быть осторожным, чтобы избежать конфликтов с существующими свойствами LayoutView при именовании вашей области.
Цепочка прототипов LayoutView:
Backbone.View > Marionette.View > Marionette.ItemView > Marionette.LayoutView
Следовательно, каждое свойство в каждом из этих классов должно быть избегаемо в качестве имён областей. Наиболее распространённая проблема, с которой сталкиваются люди, — это попытка назвать свою область «attributes». Имейте в виду, что вы этого не можете сделать.
Ниже приведён сокращённый список других имён, которые нельзя использовать в качестве имён областей. Для получения более полного списка см. документацию API для каждого класса в цепочке прототипов:
- атрибуты
- конструктор
- regionClass
- render
- destroy
- addRegion
- addRegions
- removeRegion
Примечание: это известная проблема, помеченная для исправления в версии 2
© 2016 Muted Solutions, LLC
Licensed under the MIT License.
https://marionettejs.com/docs/v2.4.7/marionette.layoutview.html