Skip to content
Grigoriev Oleg edited this page Apr 11, 2012 · 3 revisions

go.Ext.Nodes: обработка DOM-элементов

@uses: расширение требует для своей работы jQuery.

Рассмотрим следующий виджет.

<div class="window-widget">

    <div class="title">Search</div>

    <ul class="menu">
        <li class="maximize">max</li>
        <li class="minimize">min</li>
        <li class="close">close</li>
    </ul>

    <input type="text" />
    <button>Ok</button>
    
    <div class="autocomplete"></div>
    
</div>

Виджет представляет собой окно с поисковой строкой. В нём присутствуют следующие элементы:

  • Текстовое поле, куда пользователь вводит то, что ищет.
  • Кнопка, которую жмут для начала поиска.
  • Слой в котором отрисовываются варианты автокомплита при вводе.
  • Заголовок.
  • Верхнее меню, как у обычного окна: развернуть, минимизировать, скрыть.

Следующий класс определяет поведение виджета (в конструкторе получает контейнер виджета):

var WindowWidgetClass = go.Class({

    '__construct': function (node) {
        this.node = $(node);
        this.loadNodes();
        this.initEvents();        
    },
    
    '__destruct': function () {
        this.doneEvents();
    },
    
    'loadNodes': function () {
        this.nodeTitle     = this.node.find(".title");
        this.nodeMaximize  = this.node.find(".maximize");
        this.nodeMinimize  = this.node.find(".minimize");
        this.nodeClose     = this.node.find(".close");
        this.nodeText      = this.node.find("input");
        this.nodeSubmit    = this.node.find("button");
        this.nodeAComplete = this.node.find(".autocomplete");
    },
    
    'initEvents': function () {
        this.nodeMaximize.bind("click", this.onClickMaximize);
        this.nodeMinimize.bind("click", this.onClickMinimize);
        this.nodeClose.bind("click", this.onClickClose);
        this.nodeText.bind("keypress", this.onKeypressText);
        this.nodeSubmit.bind("click", this.onClickSubmit);
    },
    
    'doneEvents': function () {
        this.nodeMaximize.unbind("click", this.onClickMaximize);
        this.nodeMinimize.unbind("click", this.onClickMinimize);
        this.nodeClose.unbind("click", this.onClickClose);
        this.nodeText.unbind("keypress", this.onKeypressText);
        this.nodeSubmit.unbind("click", this.onClickSubmit);    
    },
    
    'onClickMaximize': function () { /* ... */ },
    'onClickMinimize': function () { /* ... */ },
    'onClickClose': function () { /* ... */ },
    'onClickKeypressText': function () { /* ... */ },
    'onClickSubmit': function () { /* ... */ },

    'eoc': null
});

То есть класс виджета должен:

  • Достать из своего контейнера все элементы.
  • Повесить на них обработчики нужных событий.
  • В момент разрушения, желательно, все обработчики снять.

Кроме того, хорошо бы писать не так:

this.nodeTitle = this.node.find(".title");

а вынести все используемые селекторы в константы.

go.Ext.Nodes

Наше расширение позволяет несколько автоматизировать всю эту рутину. С ним вышеприведённый класс можно сначала упростить так:

var WindowWidgetClass = go.Class(go.Ext.Nodes, {

    'nodes': {
        'title'     : ".title",
        'maximize'  : ".maximize",
        'minimize'  : ".minimize",
        'close'     : ".close",
        'text'      : "input",
        'button'    : "button",
        'acomplete' : ".autocomplete"
    },

    '__construct': function (node) {
        this.initNodes(node); // or go.Ext.Nodes.__construct(this, node);
        this.initEvents();
    },
    
    '__destruct': function () {
        this.doneNodes(); // or go.Ext.Nodes.__destruct(this);
    },
   
    'initEvents': function () {
        this.bind(this.nodes.maximize, "click", "onClickMaximize");
        this.bind(this.nodes.minimize, "click", "onClickMinimize");
        this.bind(this.nodes.close, "click", "onClickClose");
        this.bind(this.nodes.text, "keypress", "onKeypressText");
        this.bind(this.nodes.click, "click", "onClickSubmit");
    },
    
    'onClickMaximize': function () { /* ... */ },
    'onClickMinimize': function () { /* ... */ },
    'onClickClose': function () { /* ... */ },
    'onClickKeypressText': function () { /* ... */ },
    'onClickSubmit': function () { /* ... */ },

    'eoc': null
});

Для использования возможностей расширения, следует унаследовать свой класс от go.Ext.Nodes (подойдёт и множественное наследование), а в конструкторе вызвать и его конструктор (или проще initNodes()). В деструкторе, желательно, вызвать деструктор go.Ext.Nodes (или проще doneNodes()).

bind() / unbind() / unbindAll()

bind(node, eventType, handler) - установить обработчик события unbind(node, eventType, handler) - снять обработчик события

  • node (mixed) - указатель на элемент (jQuery-объект, селектор или DOM-элемент).
  • eventType (string) - тип события ("click", "keypress").
  • handler (function|string) - функция-обработчик (или имя метода текущего класса).

unbindAll() - снять все обработчики, установленные ранее через bind().

От bind'а из jQuery отличается немногим:

  • Все обработчики автоматически снимаются в деструкторе (или через unbindAll).
  • Можно использовать имя метода, а не только объект функции.
  • Ну и просто некоторое абстрагирование от jQuery.

nodes и node

Передаваемый в конструктор аргумент node указывает на контейнер, в котором содержится реализуемый виджет. Это может быть jQuery-объект, его селектор или DOM-элемент. Либо контейнер можно вообще не указывать.

jQuery-объект контейнера впоследствии доступен через свойство nodes.

В nodes указываются элементы виджета, которые требуется загрузить, в формате название => селектор. После отработки конструктора там уже содержатся сами элементы (их jQuery-объекты).

При указании контейнера, элементы ищутся внутри него. Без указания - глобально.

Формат nodes

Элементы в nodes могут определятся не просто селектором, но и объектом со следующими параметрами:

  • selector (string): собственно, опять-таки селектор.
  • global (bool): по умолчанию, если указан объемлющий контейнер, элементы ищутся по селекторам внутри него. Указание global заставляет искать данный элемент глобально в документе.
  • creator (function): функция, создающая элемент.

// @todo

Наследование

Clone this wiki locally