- PVSM.RU - https://www.pvsm.ru -

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

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

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

Идея Backbone.Component во многом близка веб-компонентам и компонентам в Ember.js [4]. Каждый компонент — это изолированный элемент 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 [5]
Там же можно найти более подробную документацию.
Backbone.Component доступен в Bower [6] под именем backbone_component. Если вы используете Bower, установить Backbone.Component можно из консоли bash:

bower install backbone_component

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

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

Поскольку плагин появился недавно, вполне вероятно он содержит баги и недочёты. Любые сообщения о таковых, а тем более пулл-реквесты с исправлениями, с благодарностью принимаются в репозитории проекта. Единственная просьба: используйте английский язык, уважайте opensource-сообщество.
Ну и разумеется можете писать здесь любые свои замечания.
Вот и всё, спасибо за внимание. Надеюсь этот плагин поможет кому-то в его непростом деле разработки сложных веб-приложений.

Автор: malroc

Источник [9]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/52443

Ссылки в тексте:

[1] Backbone.js: http://backbonejs.org

[2] Backbone.Marionette: http://marionettejs.com

[3] Base: https://github.com/steve8708/base

[4] Ember.js: http://emberjs.com

[5] https://github.com/malroc/backbone-component: https://github.com/malroc/backbone-component

[6] Bower: http://bower.io

[7] MutationObserver: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

[8] например: https://github.com/Polymer/MutationObservers

[9] Источник: http://habrahabr.ru/post/208600/