Skip to content

Widgets

Pavel Motorin edited this page May 29, 2013 · 10 revisions

Widgets module

Для подключения js-виджетов, которые должны работать только в рамках какого-то блока, нужно использовать атрибут data-js-widgets="...". При желании, можно указать несколько таких виджетов через запятую.

    <div data-js-widgets="/js/some_widget1.js, /js/some_widget2.js"></div>
    <div></div>
</section>

Этот атрибут можно указать у любого DOM-элемент. При инициализации виджета этот элемент будет передан ему соответствующим параметром.

Structure

Виджеты пишутся по стандарту AMD. Определяющая функция должна возвращать объект, который расширяет базовый интерфейс.

Пример минимально достаточного виджета:

define([], function(){
    return {}
});

API

define([], function(){
    return {
        domEvents: 
            (см. ниже domEvents)
        },
        moduleEvents: {
            (см. ниже moduleEvents)
        },
        init: function( rootElement ){
            # Опциональная функция. Вызывается в самом начале, если определена.
            # В качестве rootElement получает ссылку на DOM-элемент, к которому
            # этот виджет был подключен
        },
        turnOn: function(){
            # Optional function.
            # Вызывает в ситуации, когда виджет "включается". 
        },
        turnOff: function(){
            # Optional function.
            # Вызывается в ситуации, когда виджет "выключается". 
            # Используется очень редко. Имеет смысл использовать 
            # Только для отписки от событий, которые были навешены
            # вручную внутри turnOn()
        }
    }
});

Для более аккуратной работы с памятью и для предотвращения лишних утечек рекомендуется использовать соответствующие поля — domEvents и moduleEvents.

Поле domEvents

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

domEvents: {
  "click #someId": "callbackName",
  "click #someSecondId": someFunction,
  "click #someThirdId": function(evt, element){ … }
}
callbackName: function(evt, element) {
    # evt — стандартный объект события
    # element - DOM-node, на которой произошло событие (клик мышкой)
    # this — контекст объекта самого виджета (важно!)
}
    

Обратите внимание, что someFunction, также как и анонимная функция вызовутся тоже в контексте этого виджета.

Поле moduleEvents

Используется для подписки на кастомные события, использующиеся внутри архитектуры, либо в других таких же виджетах. События таково рода проходят глобально, через внутренний модуль events.

moduleEvents: {
    "someCustomEventName": "callbackName"
}
callbackName: function(data){
   # data — сопроводительные данные, если таковые были в момент генерации события
}

Методы turnOn() и turnOff()

Optional functions. Используются очень редко.

turnOn() — для навешивания событий, которые никак нельзя навесить через domEvents и moduleEvents. Вызывается автоматически при первой инициализации и в моменты «включения» виджета — например, когда пользователь идет назад по истории.

turnOff() — для отписки от таких «ручных» событий. Вызывается в моменты «выключения» виджета. Например, когда DOM-элемент, к которому приписан виджет, изымается из DOM дерева.

Например: window.onscroll, window.onresize или что-то еще подобное.

Тем не менее, если есть возможность всю работу, например, с window.onscroll вынести в отдельный модуль, который будет триггерить нужные события через events (см. ниже), то лучше это сделать.

turnOn: function() {
    $(window).on("scroll.myWidget", $.proxy(@_onScroll, @))
},
turnOff: function() {
    $(window).off("scroll.myWidget")
},
_onScroll: function(evt) {
    # … some actions on scrolling …
}

Полезное

Создание событий для других виджетов

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

define(["events"], function(events){
    init: function(element){
    
        events.trigger("my-widget-event", [customData1, customData2, ...])
    }
});

В таком случае в другом виджете (или, если угодно, в том же самом ;) подписка будет выглядеть таким образом:

define([], function(events){
    moduleEvents: {
        "my-widget-event": "myWidgetEventCallback"
    }
    myWidgetEventCallback: function(data){
       # data = [customData1, customData2, …]
    }
    init: function(element){    
        # ...
    }
});
Clone this wiki locally