-
Notifications
You must be signed in to change notification settings - Fork 1
Ext Nodes
@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");
а вынести все используемые селекторы в константы.
Наше расширение позволяет несколько автоматизировать всю эту рутину. С ним вышеприведённый класс можно сначала упростить так:
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(node, eventType, handler)
- установить обработчик события
unbind(node, eventType, handler)
- снять обработчик события
-
node
(mixed) - указатель на элемент (jQuery-объект, селектор или DOM-элемент). -
eventType
(string) - тип события ("click", "keypress"). -
handler
(function|string) - функция-обработчик (или имя метода текущего класса).
unbindAll()
- снять все обработчики, установленные ранее через bind()
.
От bind'а из jQuery отличается немногим:
- Все обработчики автоматически снимаются в деструкторе (или через
unbindAll
). - Можно использовать имя метода, а не только объект функции.
- Ну и просто некоторое абстрагирование от jQuery.
Передаваемый в конструктор аргумент node
указывает на контейнер,
в котором содержится реализуемый виджет.
Это может быть jQuery-объект, его селектор или DOM-элемент.
Либо контейнер можно вообще не указывать.
jQuery-объект контейнера впоследствии доступен через свойство nodes
.
В nodes
указываются элементы виджета, которые требуется загрузить, в формате
название => селектор
.
После отработки конструктора там уже содержатся сами элементы (их jQuery-объекты).
При указании контейнера, элементы ищутся внутри него. Без указания - глобально.
Элементы в nodes
могут определятся не просто селектором, но и объектом со следующими параметрами:
-
selector
(string): собственно, опять-таки селектор. -
global
(bool): по умолчанию, если указан объемлющий контейнер, элементы ищутся по селекторам внутри него. Указаниеglobal
заставляет искать данный элемент глобально в документе. -
creator
(function): функция, создающая элемент.
// @todo