Этот пост представляет собой маленькое и скромное howto из разряда «Хозяйке на заметку».
Когда я только начинал знакомиться с ExtJS, для меня было несколько дико, что такой крупный каркас веб-разработки не содержит никаких средств для использования гиперссылок в пользовательском интерфейсе (по крайней мере наравне с кнопками, панельками и прочими более сложными контролами, которые можно внедрить куда угодно). Как это часто бывает, фреймворк, который дает простой путь для сложных вещей, создает сложности в тех местах, где их и не ожидаешь.
Разумеется, средствами Ext.Element (кроссбраузерной обертки вокруг dom-элементов) можно в режиме выполнения сделать инъекцию любого фрагмента HTML, но той гибкости и легкости, с которой другие контролы можно вставить, например, в тулбар, панельку или другой контейнер, добиться будет очень сложно.
И вот недавно, работая над прототипом одного приложения, я «случайно» написал такой компонент. Он очень прост, но, как мне кажется, многим мог бы облегчить жизнь.
Ниже прилагается его код и краткий разбор.
Такая гиперссылка добавляется в контейнер так же, как и любой другой стандартный компонент; взаимодействие с окружающей средой происходит в привычном событийно-ориентированном стиле.
Ссылка не привязана к заранее заданному dom id, но синтаксически гарантируется, что метод, вызванный в 'onclick' ссылки будет вызван от имени правильного компонента (как известно, при вызове метода method в виде A.method() гарантируется, что this внутри метода будет указывать на A)
Ниже приводится пример использования такого компонента.
В идеале для гиперссылки следует сделать возможность разрешать/запрещать экранирование HTML-небезопасных символов при задании свойства text. Делается это тривиально с помощью стандартной функции Ext.util.Format.htmlEncode(). Такое улучшение я предлагаю читателю в качестве небольшого упражнения.
Когда я только начинал знакомиться с ExtJS, для меня было несколько дико, что такой крупный каркас веб-разработки не содержит никаких средств для использования гиперссылок в пользовательском интерфейсе (по крайней мере наравне с кнопками, панельками и прочими более сложными контролами, которые можно внедрить куда угодно). Как это часто бывает, фреймворк, который дает простой путь для сложных вещей, создает сложности в тех местах, где их и не ожидаешь.
Разумеется, средствами Ext.Element (кроссбраузерной обертки вокруг dom-элементов) можно в режиме выполнения сделать инъекцию любого фрагмента HTML, но той гибкости и легкости, с которой другие контролы можно вставить, например, в тулбар, панельку или другой контейнер, добиться будет очень сложно.
И вот недавно, работая над прототипом одного приложения, я «случайно» написал такой компонент. Он очень прост, но, как мне кажется, многим мог бы облегчить жизнь.
Ниже прилагается его код и краткий разбор.
Custom.Hyperlink = Ext.extend(Ext.BoxComponent, {
constructor: function (config) {
config = config || {};
Ext.apply(this, config);
Custom.Hyperlink.superclass.constructor.call(this, config);
this.on('afterrender', this.createHref, this);
this.addEvents('clicked');
},
hrefTpl: '<a href="#" onclick="Ext.getCmp(\'{0}\').notifyClicked(); return false;">{1}</a>',
createHref: function () {
var tpl = new Ext.Template(this.hrefTpl),
html = tpl.apply([this.getId(), this.text]);
this.el.update(html);
},
notifyClicked: function () {
this.fireEvent('clicked', this);
}
}
);
Ext.reg('hyperlink', Custom.Hyperlink);
Такая гиперссылка добавляется в контейнер так же, как и любой другой стандартный компонент; взаимодействие с окружающей средой происходит в привычном событийно-ориентированном стиле.
Ссылка не привязана к заранее заданному dom id, но синтаксически гарантируется, что метод, вызванный в 'onclick' ссылки будет вызван от имени правильного компонента (как известно, при вызове метода method в виде A.method() гарантируется, что this внутри метода будет указывать на A)
Ниже приводится пример использования такого компонента.
Custom.SearchPanel = Ext.extend(Ext.Panel, {
initComponent: function () {
Ext.apply(this, {
… //skipped
tbar: [{
xtype: 'hyperlink',
text: 'Show advanced',
listeners: {
scope: this,
clicked: this.showAdvancedForm
}
}
]
}
);
Custom.SearchPanel.superclass.initComponent.call(this);
},
showAdvancedForm: function () {
Ext.Msg.alert('Clicked!');
}
}
);
В идеале для гиперссылки следует сделать возможность разрешать/запрещать экранирование HTML-небезопасных символов при задании свойства text. Делается это тривиально с помощью стандартной функции Ext.util.Format.htmlEncode(). Такое улучшение я предлагаю читателю в качестве небольшого упражнения.