Использование Marionette.Region для создания загрузочных представлений

Использование Marionette.Region для создания загрузочных представлений

499

В данной статье я обрисую метод , позволяющий достигнуть такового поведения за счёт повторно используемой области Marionette.Region в MarionetteJS. В клиентских приложениях чрезвычайно нередко возникает необходимость как-то визуализировать процесс загрузки данных с сервера.

Сходу скажу, что мой подход во многом основывается на подходе создателя скринкастов на www.backbonerails.com. Это чрезвычайно отменная и нужная серия скринкастов не лишь (и не столько) с точки зрения того, что дискуссируется тут, но и в целом для исследования MarionetteJS.

Цель
Итак, нашей целью является разработка повторно используемого компонента для MarionetteJS, занимающегося визуализацией процесса загрузки. Как будет показано далее, в случае Backbone/Marionette действия начала и окончания загрузки можно считать личным случаем конфигурации состояния модели, потому назначение этого компонента можно сконструировать наиболее абстрактно как визуализацию конфигурации состояния модели.

Начинаем с BackboneJS
Допустим, у нас есть модель (либо коллекция) и представление, которое её показывает. Как всем отлично понятно, MarionetteJS является надстройкой над BackboneJS. На уровне BackboneJS поставленную задачку мы могли бы решить последующим образом: И я бы желал начать с того, как Backbone может посодействовать с решением данной задачки.

Набросок 1 — Действия модели при загрузке данных

Для краткости, я буду именовать способность реагировать на действия конфигурации состояния модели такие как request, sync, error и т.п. Под конфигурацией состояния я имею в виду любые действия, не связанные с конфигурацией данных модели. То есть нехитрая мысль состоит в том, что представление обозревает модель и употребляет действия request и sync, генерируемые Backbone.Model, для перехода к «загрузочному» (к примеру, рисует какую-нибудь анимацию загрузки) либо к «синхронизированному» состоянию (убирает анимацию загрузки). отзывчивостью.

В общем, Backbone дозволяет нам просто достигнуть подходящего поведения, за счёт событий, генерируемых Backbone.Model (либо Backbone.Collection), но есть трудности с повторным внедрением кода, который должен подписаться на действия модели и обработать их. Я не буду останавливаться на дальнейших рассуждениях, как можно было бы воплотить наш компонент на базе Backbone, поэтому что в любом случае лучше, чем на базе MarionetteJS, он не получится. Фактически, с вопросцем как воплотить отзывчивость заморочек не возникает, основной вопросец где это можно сделать, чтоб внедрение данной реализации было более ненавязчивым и комфортным.

Используем представления MarionetteJS
Гугление находило несколько дискуссий, насчёт реализации атрибута Marionette.View.loadingView аналогично Marionette.CollectionView.emptyView. Когда я в 1-ые столкнулся с задачей визуализации загрузки, я не задумывался, что по этому вопросцу будет так не достаточно готовых решений. Т.е. В общем случае, метод визуализации загрузки зависит не от представления модели, а от того, кто его показывает. Короче говоря, этот вариант нам не подступает. раз мы отображаем различные модели в одном и том же месте документа, то и визуализация загрузки обязана смотреться единообразно для всех их. Позднее возникло и какое-то готовое решение. Но честно говоря, я считаю, что визуализация загрузки модели на уровне представления, конкретно отображающего эту модель, не самая наилучшая мысль.

Используем контроллеры MarionetteJS
Это подход описан в этом выпуске уже упоминавшейся серии скринкастов. Вот в общих чертах этот подход: Раз в 2-ух словах, этот подход употребляет модель как источник событий и базисный абстрактный контроллер, определяющий метод отображения представлений. Сейчас пришло время поведать о подходе, на базе которого появилась моя мысль.
Конкретно отзывчивость реализуется парой LoadingControler+LoadingView.
Для работы с LoadingView употребляется способ базисного класса контроллера show(view, region, options). Дальше LoadingController сходу же в собственном конструкторе (а не по событию request) подставляет LoadingView в указанную область. Производные контроллеры должны применять этот способ для отображения представлений. Этот способ в свою очередь делает экземпляр LoadingController и передаёт ему начальное представление и область для отображения.
При этом, что комфортно, модель можно не указывать очевидно, по умолчанию будут обозреваться RealView.collection и RealView.model. Наиболее непосредственно, LoadingController обозревает не модель, а объекты xhr, ассоциированные с запросом данных данной модели. По завершении этих запросов заместо LoadingView в ту же область вставляется RealView. LoadingController обозревает модель.

Набросок 2 – Диаграмма последовательности при использовании LoadingView+LoadingController

ЗамечанияLoadingController работает с LoadingView и RealView не впрямую, а через Marionette.Region, но для общего осознания работы это не принципиально.

Вот диаграмма классов, которые участвуют в этом содействии:

Набросок 3 – Диаграмма классов при использовании LoadingView+LoadingController

Но мне он не подошёл по той причине, что он налагает некие требования на общую архитектуру приложения: Это 1-ый стоящий подход из тех, что уже упоминались.
Все контроллеры должны наследоваться от 1-го базисного класса, и применять лишь его способ для отображения представлений.
Для отображения загрузочного представления нужно непременно следовать последовательности: начать загрузку модели, сделать новое представление, показать его.

В то же время есть чрезвычайно удачные решения, которые я позаимствовал:
Возможность определения модели, которую требуется обозревать, без явного указания на неё.
Ответственность за визуализацию загрузки выносится за рамки представления модели.

Используем Marionette.Region
Marionette.Region олицетворяет какую-то область экрана, в которой располагаются представления, и дозволяет управлять временем жизни представления и отделять от представления метод его возникновения на экране. Для примера, в этом выпуске как раз описывается реализация своей области, оборачивающей случайное представление в диалоговое окно. Раз для вас необходимо поменять метод возникновения представления на экране, вы сможете просто унаследоваться от Marionette.Region и воплотить свою логику. К примеру, вы сможете поменять метод возникновения, добавив анимацию, а сможете поменять метод вставки представления в документ, оборачивая его какими-то своими элементами. Раз вы желаете показать в области представление, для вас не необходимо мыслить, что будет с тем представлением, которое уже помещено в область — оно будет удалено автоматом.

К примеру, можно поменять прозрачность, видимость частей области, вставлять какой-нибудь оверлей с анимацией, — в общем, делать всё что угодно. Я не буду уделять много внимания оформительской части, а сосредоточусь на абстрактном классе. В моей реализации основная работа происходит в абстрактном классе ResponsiveRegion, являющимся наследником Marionette.Region. Вот как я воплотил отзывчивость на уровне области при помощи ResponsiveRegion: Определенным классам остаётся лишь найти обработчики, меняющие изменяется наружный вид области в зависимости от событий модели (и перечислить сами модели).

Инициализация ResponsiveRegion не различается Marionette.Region. Допустим, представление Layout (производное от LayoutView), определяющее область, показывает (декларативно), что обязана употребляться наша реализация области ResponsiveRegion, а не обычный Marionette.Region.

List.Layout = Marionette.LayoutView.extend({
… }); regions : {
someRegion : {
selector : ‘#region’,
regionClass : Marionette.ResponsiveVisiblityRegion
}
}

Чтоб показать представление в данной области, можно применять region.show(view) (как с обыденным Marionette.Region), тогда будут употребляться характеристики по умолчанию, а можно через region.show(view, options) и указать расширенные опции отзывчивости.
Она может делать это не впрямую, а через обёртку. Область помещает переданное представление в документ.

Пример <div class=”js-model-state-sync”>
Сюда помещается начальное представление
</div>
<div class=”js-model-state-request”>
Вид при загрузке модели
</div>
<div class=”js-model-state-error”>
Вид при ошибке загрузки модели
</div>

К примеру переключает видимость частей обёртки. Область обозревает модель находящегося в ней представления (модель указывается или очевидно в region.show(view, options), или неявно употребляются RealView.collection и RealView.model). В зависимости от действия request/sync/error область изменяет наружный вид собственного содержимого.

Диаграмма последовательностей смотрится так:

Набросок 4 — Диаграмма последовательности при использовании ResponsiveRegion

А классов так:

Набросок 5 — Диаграмма классов при использовании ResponsiveRegion

1-ая связь опущена в силу того, невзирая на то, что практически представление Layout и зависит от ResponsiveRegion, реально оно работает с ним как c обыденным Marionette.Region. Замечания Реально есть ещё зависимости Layout и Controller от ResponsiveRegion. Просто удобнее объявлять тип области в объявлении Layout. 2-ая связь опущена, так как она необязательна и возникает лишь раз контроллеру будет нужно указать функции отзывчивости.

Чего же мы достигнули, применив таковой подход?
ResponsiveRegion в большинстве случаев употребляется также как его предок, и не делает каких-то доп догадок о компонентах, с которыми он употребляется. Мы на сто процентов уложились в структуру объектов MarionetteJS, не создав ни одной новейшей сути, а лишь расширив Marionette.Region. По сопоставлению с предшествующим подходом на базе абстрактного контроллера нет никакой завязки на то, как скооперировано ваше приложение: раз вы используете Marionette, вы сможете применять ResponsiveRegion.
ResponsiveRegion, как наследник Marionette.Region, естественным образом осведомлён о прекращении существования представления, что дозволяет ему в подходящий момент отписываться от событий модели и не оставлять за собой мусор. Мы обозреваем модель всё время, пока её представление находится в ResponsiveRegion.
Это дозволяет свободно реагировать на остальные действия модели, такие как ошибка загрузки либо валидация данных модели. Событие начала и окончания загрузки модели мы рассматриваем как личный вариант конфигурации её состояния, которое может происходить случайное число раз за время жизни модели.

Заключение
Все из рассмотренных подходов могут удачно применяться в зависимости от ситуации. Во-первых, это как раз тот компонент, который в Marionette отвечает за отображение представлений на экране. Начальный код того, о чём тут говорилось, и маленький пример доступны тут. Но я считаю для визуализации конфигурации состояния модели вообщем и загрузки её данных в частности, вариант с Marionette.Region подступает лучше всего. А во-вторых, нужная логика довольно проста, чтоб её можно было воплотить снутри 1-го компонента. На этом всё.

Ссылки
backbonerails.com — cерии скринкастов по MarionetteJS
Документация MarionetteJS
Перечень событий BackboneJS habrahabr.ru