Про Marionette.js

23 Июня 2016 4416 , , ,

marionetteВ сети сейчас можно найти много статей про модные ныне javascript фреймворки. Такие как Angular, React, Ember , Polymer воплощающие в себе достаточно интересные идеи и подходы + использующие относительно новые подходы при работе с веб страницей (прим. shadow-dom) и позволяющие делать восхитительные вещи, не без костылей конечно, но это уже другой разговор. Но есть еще один достаточно крупный фреймворк и это Marionette.js некоторые «продвинутые» фанаты мейнстримного фронтенда для себя похоронили этот фреймворк вместе с backbone. Но проект успешно продолжает развиваться и представляет из себя очень хороший фундамент для создания ваших веб приложений. И так будет еще очень долго, пока HTML5 и новые версии фундаментально не придумают что-то иное как работа с DOM. Так что за жизнь marionette можно не переживать.

За что я люблю marionette?

Все началось с backbone, это по сути не фреймворк, а библиотека реализующая некоторые абстрактные понятия, такие как Model, View, Collection а также Router и Sync, но это уже второстепенные возможности. Каждое из этих понятий вы конечно же можете extend’ить как вам захочется и понравится. Можно легко реализовать классический MVC, можно MVVM, MVP. если хочется можно и publisher subsciber реализовать. Это и есть фундаментальная свобода для разработки и масштабирования архитектуры под любые нужды клиента. Но такой подход далеко не всем понравится в силу того, что придется писать много шаблонного кода. Объяснять view как ей делать render, расписывать примитивные связи абстракций типа CollectionView ModelView и т.п. это еще одна слабая сторона backbone, это то, что биндинг данных в view лежит на разработчике очень плотно и заставляет писать некоторый «шаблонный код». Более популярные js фреймворки предоставляют разработчикам более высокие слои абстракции, что позволяет им делать за «5 минут» что-то типичное, но как только надо, вот прям надо бизнесу отойти от текущего бизнес процесса, или срочно внести что-то новое, вам придется побороться с этими самыми правилами наложенными на вас фреймворком.  Вернемся к Marionette, это уже backbone фреймворк, как раз предостовляющий более конкретные объекты с которыми можно оперировать на более высоком уровне, которые в свою очередь унаследованы от абстракций backbone.

Рассмотрим поближе

Первое, что предлагает нам marionette это конечно само понятие Application в котором инициализация и старт приложения это разные понятия, также поддерживается событийная модель. Давайте попробуем написать наше первое приложение.

Пример из доки. Давайте немного усложним сами. И представим как могло бы выглядеть приложение немного побольше простого примера.

Я буду писать в ES5 стиле т.к. статья в первую очередь расчитана на начинающих в фронтенд разработке и не знакомых хорошо с ES6 синтаксисом. Но для продвинутого пользователя, могу сказать, что можно в целом писать и в таком виде

Примеры с ES6 + Marionette можно посмотреть на github.

Если в целом окинуть взглядом документацию Marionette, можно заметить, что большинство абстракций это абстракции как раз для View. В marionette действительно создан замечательный механизм для работы с самого разного рода Views и следует уделить особое внимание работе с архитектурой views приложения. Люди начинающие программировать на Marionette часто путаются, когда и какой следует применить подход, чтобы не раздуть приложение и при этом сохранить баланс между раздутием и экономией на спичках.

Самым высоким уровнем абстракции View можно назвать Region который сам по себе то и не является полноценной View а лишь предоставляет интерфейс для отображения какой-то view. Вы можете подписываться не действия региона, реагировать на show, hide, render, swap и другие события, когда стоит применять регионы? Я рекомендую применять их только в том случае, когда в данном контексте подразумевается, что в этом месте может быть отображена другая View. К примеру в своих приложениях я использую на верхнем уровне один регион layout внутри которого может быть показана любая View от страницы с ошибкой до любого другого интерфейса. Например в главном интерфейсе пользователя PageView который унаследован от Mn.LayoutView есть 2 View это SidebarView унаследованная от Mn.AbstractView и регион page в котором отображаются Views разделов из Sidebar. Таким образом я подразумеваю, что sidebar у меня в рамках главной View неизменен, а в регионе page views  будут меняться и представлять из себя разные другие Views. На мой взгляд, на уровне кода, абстракции и логики это достаточно лаконичное описание и сам подход к разработке приложения. В итоге я могу обратиться например так App.layout.currentView.sidebar и к текущей pageView  App.layout.currentView.page.currentView как говорят —  почувствуйте разницу.

Также вам скорее всего придется показывать различные Collections и для этого уже подготовлена для вас Mn.CollectionView которая принимает Collection, childVIew — View которая должна использоваться для отображения конкретной модели. В свою очередь для отображения модели уже подготовлена для вас Mn.ItemView. Стоить обратить внимание, что Mn.ItemView можно использовать не только внутри Mn.CollectionView но и как самостоятельную View представляющую какую-то одну модель данных. Если вам необходимо отобразить коллекцию + например фильтр для нее или еще какие-то доп данные. Можно использовать Mn.CompositeVIew которая помимо функций работы с collection  у Mn.CollectionView также работает еще и с model. Ну а если хочется совсем сложных изысков, abstract view и регионы вам в этом помогут. Стоит также отметить, что не редки случаи использования в качестве View того же Knockout или React есть и такой симбиоз, правда с Backbone и без Marionette, правильной архитектуре такой союз никак не повредит и имеет право на жизнь.

Ближе к HTML

Теперь давайте рассмотрим View уже чуть ближе к интерфейсам и работе с html. Сама по себе View это по сути node element который мы создаем в JavaScript с помощью document.createElement В Marionette на уровне архитектуры, подразумевается, что у типичной View должен быть реализован метод render который связывает между собой данные модели и сам шаблон. Обычно, сама модель ничего не знает о той View, что ее показывает, а вот View имеет ссылку на model или viewmodel (в зависимости от вашего подхода варианты могут быть разные) которую она сейчас представляет. По своей сути метод render выглядит вот так

Теперь посмотрим как может выглядеть template

Возможность переопределить стандартное поведение рендеринга данных дает разработчику огромную гибкость в плане контроля частоты обновления DOM и сокращения событий reflow и repaint в браузере. + возможность кеширования шаблонов дает ощутимый прирост в скорости сбора templates.

Также из удобств marionettе предоставляет сахарок в виде объектов events и ui, где мы можем сохранить ссылки на элементы view для сокращения выборки в DOM а также лаконичное описание

А что если без SPA?

Немного отвлечемся от модного SPA. Предположим вы работаете на каком-нибудь среднестатистическим проекте на Yii или Symfony, где подходы SPA изначально не практикуются т.к. в этой среде принято делать фронт немного иначе и почти вся это философия с логикой Views никому нафиг не нужна. Легче и быстрее jQuery спаггети стайл или symfony\yii way Но на самом деле можно поддерживать приятный фронт с все той же иерархией Views рассматривая раздельные страницы как некие singletones живущие сами по себе и при инициализации не обязательно связанные с основной App как-то. Имеющие лишь ссылку через window.App при необходимости доступа к другим View из соседних js файлов. (конечно за порядком загрузки js следить никто не отменял в этом случае).

На мой взгляд это замечательная возможность скрестить два подхода, конечно если есть необходимость в этом. На своей практике сталкивался не раз и данный подход позволял мне сохранять родное для меня окружение работая с чужой технологией.

Если вы дочитали до этих строк, надеюсь мне удалось заинтересовать вас одним их подходов к построению современного фронтенда) буду рад ответить на комментарии и дополнить статью.

Подписывайтесь на обновления

Читайте RSS ленту

Комментарии

Добавить комментарий