Pull to refresh

Гиперссылки в ExtJS 2.x/3.x. В помощь молодому бойцу

Reading time2 min
Views781
Этот пост представляет собой маленькое и скромное howto из разряда «Хозяйке на заметку».
Когда я только начинал знакомиться с 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(). Такое улучшение я предлагаю читателю в качестве небольшого упражнения.
Tags:
Hubs:
Total votes 5: ↑1 and ↓4-3
Comments9

Articles