Marionette.Region
Регионы предоставляют методы для согласованного управления, показа и уничтожения представлений в ваших приложениях и макетах. Они используют jQuery-селекторы, чтобы показать ваши представления в правильном месте.
С помощью класса LayoutView
вы можете создавать вложенные регионы.
Содержание
- Определение регионов приложения
- Инициализация региона с помощью
el
- Основное применение
- События и коллбэки региона
- Собственные классы регионов
Определение регионов приложения
Вы можете добавить регионы в ваших приложениях, вызвав метод addRegions
у экземпляра вашего приложения. Этот метод ожидает один параметр в виде хэша.
В хэше заданы имена регионов и либо jQuery-селектор, либо объект Region
.
Вы можете вызвать этот метод столько раз, сколько вам нужно, и он будет продолжать
добавлять регионы в приложение.
myApp.addRegions({
mainRegion: "#main-content",
navigationRegion: "#navigation"
});
Вскоре после вызова addRegions
, ваши регионы станут доступны у объекта вашего приложения.
В приведенном выше примере myApp.mainRegion
и myApp.navigationRegion
немедленно доступны для использования.
Если вы укажете одно и то же имя для региона дважды, будет использовано последнее определение.
Вы можете также добавить регионы через LayoutView
:
var AppLayoutView = Marionette.LayoutView.extend({
template: "#layout-view-template",
regions: {
menu: "#menu",
content: "#content"
}
});
var layoutView = new AppLayoutView();
layoutView.render();
layoutView.menu.show(new MenuView());
layoutView.content.show(new MainContentView());
Типы конфигурирования регионов
Marionette поддерживает несколько способов определения регионов в вашем Application
или LayoutView
.
Селектор в виде строки
Для определения региона вы можете использовать jQuery-селектор в виде строки.
myApp.addRegions({
mainRegion: '#main'
});
Класс региона
Если у вас есть собственный класс региона, вы можете использовать его для определения региона.
Внимание: Убедитесь, что класс региона имеет свойство el
, в противном случае регион создать не получится.
var MyRegion = Marionette.Region.extend({
el: '#main-nav'
});
myApp.addRegions({
navigationRegion: MyRegion
});
Литерал объекта
Наконец, вы можете определить регионы в виде литерала объекта.
Определения в виде литерала объекта обычно содержит определенное selector
или el
свойство.
Свойство selector
это селектор в виде строки, а свойство el
может быть
как селектором в виде строки, так и Query-объектом или HTML-узлом.
Вы можете также задать свойство regionClass
для собственного класса региона.
Если ваш regionClass
уже имеет установленное свойство el
, то вам не нужно
определять selector
или el
свойство в литерал объекте.
Любые другие свойства, заданные вами в литерале объекта, будут использоваться в качестве параметров, которые будут
переданы в экземпляр региона, включая allowMissingEl
.
Обычно, регионы ожидают установку свойства el
ссылающегося на DOM элемент.
Но иногда, нужно инстанцировать и использовать регион без этого элемента. Например, регионы определяются внутри
родительского представления LayoutView
. В этом случае, можно передать опцию allowMissingEl
, подавляющую ошибку
неустановленного элемента.
var MyRegion = Marionette.Region.extend();
var MyOtherRegion = Marionette.Region.extend();
var MyElRegion = Marionette.Region.extend({ el: '#footer' });
myApp.addRegions({
contentRegion: {
el: '#content',
regionClass: MyRegion
},
navigationRegion: {
el: '#navigation',
regionClass: MyOtherRegion,
// Параметры, которые будут переданы в экземпляр `MyOtherRegion` для
// `navigationRegion` в `App`
navigationOption: 42,
anotherNavigationOption: 'foo'
},
footerRegion: {
regionClass: MyElRegion
}
});
Обратите внимание, что одним из основных преимуществ использования regionClass
с уже
установленным el
является возможность предоставления параметров для экземпляра региона.
Это невозможно, когда используется непосредственно класс региона, как в способах ранее.
var MyRegion = Marionette.Region.extend({
el: '#content',
});
myApp.addRegions({
contentRegion: {
regionClass: MyRegion,
myRegionOption: 'bar',
myOtherRegionOption: 'baz'
}
});
Смешивание и комбинирование
Конечно вы можете смешивать и комбинировать различные типы конфигурирования регионов.
var MyRegion = Marionette.Region.extend({
el: '#content'
});
var MyOtherRegion = Marionette.Region.extend();
myApp.addRegions({
contentRegion: MyRegion,
navigationRegion: '#navigation',
footerRegion: {
el: '#footer',
regionClass: MyOtherRegion
}
});
Инициализация региона с помощью el
Вы можете указать el
для региона, чтобы управлять местом, где будет создан экземпляр регион:
var myRegion = new Marionette.Region({
el: "#someElement"
});
Опция el
может также быть ссылкой на DOM-узел:
var myRegion = new Marionette.Region({
el: document.querySelector("body")
});
Также el
может быть jQuery
-оберткой для DOM-узла:
var myRegion = new Marionette.Region({
el: $("body")
});
Основное применение
Отображение представления
Как только регион объявлен, вы можете вызвать его методы show
и empty
для отображения или выключения представления:
var myView = new MyView();
// Рендеринг и отобрабражение представления
myApp.mainRegion.show(myView);
// Удаление текущего представления
myApp.mainRegion.empty();
Опция preventDestroy
Если вы хотите заменить текущее представление на новое представлние, вы можете вызвать метод show
,
этот метод, по умолчанию, автоматически уничтожит предыдущее представление. Вы можете предотвратить
это поведение передав опцию {preventDestroy: true}
в параметрах метода; больше информации можно
прочитать в События и коллбэки региона.
// Отобразим первое представление.
var myView = new MyView();
myApp.mainRegion.show(myView);
// Заменим представление на другое.
// Метод `destroy` будет вызван для вас автоматически
var anotherView = new AnotherView();
myApp.mainRegion.show(anotherView);
// Заменим представление на другое.
// Предотвращием вызов метода `destroy`
var anotherView2 = new AnotherView();
myApp.mainRegion.show(anotherView2, { preventDestroy: true });
ПРИМЕЧАНИЕ: При использовании preventDestroy: true
вы должны быть осторожны, необходимо помнить,
что ваши старые представления должны быть удалены вручную, чтобы предотвратить утечку памяти.
Опция forceShow
Если вы повторно вызовите метод show
с тем же представлением, то по умолчанию ничего
не произойдет, потому что представление уже в регионе. Вы можете заставить представление
переотобразиться (re-shown), для этого нужно передать опцию {forceShow: true}
в параметрах метода.
var myView = new MyView();
myApp.mainRegion.show(myView);
// сейчас повторный вызов метода `show` переотобразит представление
myApp.mainRegion.show(myView, {forceShow: true});
Очистка региона
Вы можете очистить регион вызвав метод .empty()
. Если желаете защитить текущее содержимое регионаот “разрушения”, можете
передать {preventDestroy: true}
в .empty()
метод. Empty()
вернет инстанс региона, при своем вызове.
onBeforeAttach & onAttach
Регионы, присоединяемы к документу вызовом show
отличаются тем, что показываемые ими представления также добавляются в документ.
Такие регионы триггерят пару методов на всех своих вложенных представлениях, даже если вложенное представление всего одно.
Это может привести к проблемам в производительности, если вы рендерите несколько сотен представлений за раз.
Если считаете, что эти события могут быть причиной некоторого лага в вашем приложении, вы можете избирательно отключить их
устанавливая triggerBeforeAttach
и triggerAttach
свойства.
// No longer trigger attach
myRegion.triggerAttach = false;
Можно передавать эту опцию, как опцию метода .show()
// Этот регион не триггерит beforeAttach
myRegion.triggerBeforeAttach = false;
// Пока мы не скажем ему это сделать
myRegion.show(myView, {triggerBeforeAttach: true});
Проверка отображено ли представление в регионе
Если вы хотите проверить, есть ли представление у региона, то вы можете использовать
функцию hasView
. Эта функция возвращает соответствующее булевское значение в зависимости от того,
отображено ли представление в регионе или нет.
Сброс региона
Регион может быть сброшен в любое время через метод reset
. Этот метод уничтожит
существующее представление, отображаемое в регионе, и удалит закэшированное значение из el
.
Затем, регион отобразит представление, значение свойства el
региона запрашивается у DOM.
myRegion.reset();
Это полезно, когда регионы используются повторно для экземпляров представления, а также в модульном тестировании.
Настройка способа добавления el
представления в DOM
Переопределение метода attachHtml
региона изменяет поведение того, как представление
будет добавлено в DOM. Этот метод принимает один параметр - представление для отображения.
По умолчанию, реализация метода attachHtml
является следующей:
Marionette.Region.prototype.attachHtml = function(view) {
this.$el.empty().append(view.el);
}
Происходит замещение содержимого региона значением/содержимым el
представления.
Вы можете переопределить метод attachHtml
для создания своего эффекта перехода
или чего-то еще.
Marionette.Region.prototype.attachHtml = function(view) {
this.$el.hide();
this.$el.html(view.el);
this.$el.slideDown("fast");
}
Кроме того, можно задать свой собственный метод отрисовки для своего региона,
наследуясь от класса Region
и добавив свою реализацию метода attachHtml
.
Этот пример задает появление представления slide-эффектом снизу вверх экрана, а не просто появление в нужном месте:
var ModalRegion = Marionette.Region.extend({
attachHtml: function(view) {
// Некоторый эффект отображения представления:
this.$el.empty().append(view.el);
this.$el.hide().slideDown('fast');
}
})
myApp.addRegions({
mainRegion: '#main-region',
modalRegion: {
regionClass: ModalRegion,
selector: '#modal-region'
}
})
Добавление существующего представления
Есть несколько сценариев, как желательно добавлять существующее представление в регион, без отрисовки или отображения представления и без замещения HTML-содержимого региона. Например, для SEO и универсального доступа часто нужен HTML, который должен сгенерироваться на сервере, а также для прогрессивного улучшения HTML.
Есть два способа сделать это:
- установить
currentView
в конструкторе региона - вызвать
attachView
у экземпляра региона
Установка currentView
при инициализации
var myView = new MyView({
el: $("#existing-view-stuff")
});
var myRegion = new Marionette.Region({
el: "#content",
currentView: myView
});
Вызов attachView
в регионе
myApp.addRegions({
someRegion: "#content"
});
var myView = new MyView({
el: $("#existing-view-stuff")
});
myApp.someRegion.attachView(myView);
События и коллбэки региона
При отображении и уничтожении представлений регион будет запускать несколько событий на самом себе и на представлении, с которым он работает.
События на регионе при выполнении метода show
before:show
/onBeforeShow
- Вызывается после того, как представление было отрендерено, но еще не отображено.show
/onShow
- Вызывается после того, как представление отрендерено и отображено.before:swap
/onBeforeSwap
- Called before a new view is shown. NOTE: this will only be called when a view is being swapped, not when the region is empty.swap
/onSwap
- Called when a new view is shown. NOTE: this will only be called when a view is being swapped, not when the region is empty.before:swapOut
/onBeforeSwapOut
- Called before a new view swapped in. NOTE: this will only be called when a view is being swapped, not when the region is empty.swapOut
/onSwapOut
- Called when a new view swapped in to replace the currently shown view. NOTE: this will only be called when a view is being swapped, not when the region is empty.before:empty
/onBeforeEmpty
- Вызывается перед тем, как представление будет очищено.empty
/onEmpty
- Вызывается после того, как представление очищено.
События на представлении при выполнении метода show
before:render
/onBeforeRender
- Вызывается перед тем, как представление будет отрендерено.render
/onRender
- Вызывается после того, как представление отрендерено, но перед тем как оно будет добавлено в DOM.before:show
/onBeforeShow
- Called after the view has been rendered, but before it has been bound to the region.before:attach
/onBeforeAttach
- Called before the view is attached to the DOM. This will not fire if the Region itself is not attached.attach
/onAttach
- Called after the view is attached to the DOM. This will not fire if the Region itself is not attached.show
/onShow
- Called when the view has been rendered and bound to the region.dom:refresh
/onDomRefresh
- Called when the view is both rendered and shown, but only if it is attached to the DOM. This will not fire if the Region itself is not attached.before:destroy
/onBeforeDestroy
- Вызывается перед уничтожением представления.destroy
/onDestroy
- Вызывается после уничтожения представления.
Note: render
, destroy
, and dom:refresh
are triggered on pure Backbone Views during a show, but for a complete implementation of these events the Backbone View should fire render
within render()
and destroy
within remove()
as well as set the following flags:
view.supportsRenderLifecycle = true;
view.supportsDestroyLifecycle = true;
Пример обработчиков событий
myApp.mainRegion.on("before:show", function(view, region, options){
// manipulate the `view` or do something extra
// with the `region`
// you also have access to the `options` that were passed to the Region.show call
});
myApp.mainRegion.on("show", function(view, region, options){
// manipulate the `view` or do something extra
// with the `region`
// you also have access to the `options` that were passed to the Region.show call
});
myApp.mainRegion.on("before:swap", function(view, region, options){
// manipulate the `view` or do something extra
// with the `region`
// you also have access to the `options` that were passed to the Region.show call
});
myApp.mainRegion.on("swap", function(view, region, options){
// manipulate the `view` or do something extra
// with the `region`
// you also have access to the `options` that were passed to the Region.show call
});
myApp.mainRegion.on("before:swapOut", function(view, region, options){
// manipulate the `view` or do something extra
// with the `region`
// you also have access to the `options` that were passed to the Region.show call
});
myApp.mainRegion.on("swapOut", function(view, region, options){
// manipulate the `view` or do something extra
// with the `region`
// you also have access to the `options` that were passed to the Region.show call
});
myApp.mainRegion.on("empty", function(view, region, options){
// manipulate the `view` or do something extra
// with the `region`
// you also have access to the `options` that were passed to the Region.show call
});
var MyRegion = Marionette.Region.extend({
// ...
onBeforeShow: function(view, region, options) {
// the `view` has not been shown yet
},
onShow: function(view, region, options){
// the `view` has been shown
}
});
var MyView = Marionette.ItemView.extend({
onBeforeShow: function(view, region, options) {
// called before the `view` has been shown
},
onShow: function(view, region, options){
// called when the `view` has been shown
}
});
var MyRegion = Marionette.Region.extend({
// ...
onBeforeSwap: function(view, region, options) {
// the `view` has not been swapped yet
},
onSwap: function(view, region, options){
// the `view` has been swapped
},
onBeforeSwapOut: function(view, region, options) {
// the `view` has not been swapped out yet
},
onSwapOut: function(view, region, options){
// the `view` has been swapped out
}
});
Собственные классы регионов
Вы можете определить свой собственный регион, наследуясь от класса Region
.
Это позволяет вам создавать новую функциональность и обеспечивает базовый
набор функциональных возможностей для вашего приложения.
Добавление собственных классов регионов
После того, как вы определите класс регион, вы можете использовать его для конфигурирования регионов в приложении.
Для этого, вы должны добавить новый класс регион в качестве значения для регион класса.
В случае использования addRegions
, указывается непосредственно сам конструктор класса регион,
а не экземпляр класса регион.
var FooterRegion = Marionette.Region.extend({
el: "#footer"
});
myApp.addRegions({
footerRegion: FooterRegion
});
Вы можете также указать селектор для региона, используя литерал объекта для конфигурирования региона.
var FooterRegion = Marionette.Region.extend({
el: "#footer"
});
myApp.addRegions({
footerRegion: {
selector: "#footer",
regionClass: FooterRegion
}
});
Обратите внимание, что регион должен иметь элемент, с которым он будет связан.
Если вы не указали селектор, когда добавляли экземпляр региона в ваше приложение или LayoutView
,
то el
региона должно быть указано либо при его определении, либо в опциях конструктора.
Создание экземпляра вашего собственного региона
Бывают ситуации, когда вы хотите добавить регион в ваше приложение
после того, как ваше приложение запустилось и работает. Что бы сделать это,
вам нужно наследоваться от класса Region
, как показано выше, и затем использовать эту
функцию конструктора по вашему усмотрению:
var SomeRegion = Marionette.Region.extend({
el: "#some-div",
initialize: function(options){
// ваш код инициализации должен быть здесь
}
});
myApp.someRegion = new SomeRegion();
myApp.someRegion.show(someView);
При желании, вы можете добавить функцию initialize
при определении
вашего класса региона, как показано в примере выше. Эта функция принимает
options
, которые были переданы в конструктор региона, аналогично тому, как это
происходит у Backbone.View
.