9 January 2014

Backbone.Component — автономные компоненты UI для Backbone.js

SourceTalk corporate blogWebsite developmentJavaScript
На нашем проекте мы используем Backbone.js в качестве основного JS-фреймворка. Почему выбор пал на него, я возможно ещё расскажу в одном из следующих постов, в этот раз речь о другом. Как известно, из коробки Backbone предлагает весьма скромные возможности, компенсируя это максимальной гибкостью. Поскольку Backbone существует достаточно давно и успел обзавестись серьёзным сообществом разработчиков, для решения многих типовых задач Backbone-приложений сегодня существуют плагины либо целые надстроенные над Backbone фреймворки (многим известен например Backbone.Marionette, очень многообещающе выглядит недавно вышедший Base — кстати советую приглядеться).
Тем не менее, есть одна достаточно распространённая задача, адекватное решения которой мне до сих пор не попадалось: речь идёт о создании типовых автономных элементов UI. Скажем, у вас в проекте используется элемент выбора даты, для его создания вы используете найденный вами на бескрайних просторах гитхаба плагин jQuery. С этим последним всё хорошо кроме того, что вам нужно вручную дёргать его каждый раз, когда на вашей странице появляется соответствующий input, а потом возможно ещё и подчищать созданную им разметку во избежание дальнейших конфликтов. В итоге вам приходится писать много повторяющегося кода. Вот здесь вам и пригодится Backbone.Component.

Использование

Идея Backbone.Component во многом близка веб-компонентам и компонентам в Ember.js. Каждый компонент — это изолированный элемент UI с собственной разметкой и логикой.

Объявление компонента
Чтобы создать собственный компонент, вам нужно объявить класс, унаследованный от Backbone.Component, и переопределить в нём 3 метода:

Backbone.Components.MyDate = Bakcbone.Component.extend(
  {
    generate: function( ) { ... },
    activate: function( ) { ... },
    deactivate: function( ) { ... }
  }
);

По порядку:
  • generate — это метод для создания разметки. Он может получать любые параметры, которые вам нужны, и должен возвращать строку (сгенерированный HTML).
  • activate — код активизации компонента. Метод не получает параметров и не возвращает значения. В нашем примере с датой он может выглядеть как-то так:
    	activate: function( ) {
    	  this.$( "input" ).datepicker( );
    	}
    	
  • deactivate — код деактивизации компонента, если таковая требуется. Также не получает параметров и не возвращает значения.

Использование в шаблонах
Вот и всё. Теперь в ваших шаблонах вы можете использовать следующий синтаксис для отрисовки компонента:

<%= this.insertMyDate( ) %>

Здесь предполагается, что this внутри шаблона указывает на объект view. Метод insertMyDate был добавлен в класс View автоматически в момент инициализации Backbone.Component (подробнее об этом моменте см. документацию), такие методы создаются для каждого компонента, который вы объявили. Все параметры, переданные методу insert..., перенаправляются без изменений в метод generate соответствующего компонента.
Как только отрисованный компонент появится на странице, для него вызовется метод activate, при его исчезновении со страницы — deactivate. Теперь вы можете использовать ваш элемент выбора даты в любом месте проекта, никак не заботясь о его инициализации и деинициализации: всё, что вам нужно — отрисовать его в шаблоне.

Использование без отрисовки
Возможно, компоненты, которые вы используете, не имеют фиксированной разметки, которую можно было бы вынести в шаблон. Например, у вас есть кастомный скроллбар, который нужно применить ко всем элементам с классом .my-scrollbar. В таком случае, вам нужно создать класс компонента MyScrollbar без метода generate, и внутри вашего объекта view (подойдёт например метод initialize) сделать следующий вызов:

this.observeMyScrollbar( ".my-scrollbar" );

Как и метод insertMyDate в предыдущем примере, метод observeMyScrollbar был сгенерирован автоматически. На вход он принимает селектор CSS. Теперь при появлении на экране элемента с классом my-scrollbar будет вызван метод activate вашего компонента, при исчезновении — deactivate. Повторный вызов метода для одного и того же селектора не даст никакого эффекта, так что можете не беспокоиться о том, сколько раз будет вызван метод observe.

Установка, документация, зависимости

Репозиторий проекта на гитхабе:
https://github.com/malroc/backbone-component
Там же можно найти более подробную документацию.
Backbone.Component доступен в Bower под именем backbone_component. Если вы используете Bower, установить Backbone.Component можно из консоли bash:

bower install backbone_component

Или прописав backbone_component в зависимостях вашего проекта.
Внешних зависимости у плагина всего две: собственно Backbone и Underscore (последний является жёсткой зависимостью и для самого Backbone). jQuery/Zepto/что-там-ещё можете не использовать, но как и в случае с Backbone, лишитесь части удобных методов для работы с DOM (см. документацию).
Кроме того, Backbone.Component построен с использованием MutationObserver. Если планируете поддерживать браузеры, в которых он не реализован (а на данный момент это все IE версии ниже 11), вам придётся использовать полифил (ну например).

Обратная связь

Поскольку плагин появился недавно, вполне вероятно он содержит баги и недочёты. Любые сообщения о таковых, а тем более пулл-реквесты с исправлениями, с благодарностью принимаются в репозитории проекта. Единственная просьба: используйте английский язык, уважайте opensource-сообщество.
Ну и разумеется можете писать здесь любые свои замечания.
Вот и всё, спасибо за внимание. Надеюсь этот плагин поможет кому-то в его непростом деле разработки сложных веб-приложений.
Tags:backbone.jsкомпоненты
Hubs: SourceTalk corporate blog Website development JavaScript
+13
10.1k 61
Comments 45
Top of the last 24 hours