В этой статье разберём механизм загрузки компонента в админке MODX, логика которой основана на ExtJs. Для людей, далеких от php и javascript, это будет набором непонятных слов. А вот те, кого уже не пугают такие термины как ООП, наследование, конструкторы, поймут о чем я тут буду говорить. Это не курс. Я просто попытаюсь систематизировать информацию для понимания общего принципа работы админки.

В сети достаточно много различной информации об ExtJs. Есть отличный курс Василия, по которому многие учились делать свои дополнения. В нем он разбирает тему создания различных ExtJs объектов. Я не буду повторять, то что у него уже разобрано, а постараюсь на простом языке сделать короткую выжимку.

Загрузка компонента modExtra

Работа админки построена на контроллерах. Нажимаете на пункт меню какого-нибудь приложения, вызывается соответствующий контроллер, который по цепочке запускает ряд действий (у Василия подробно это расписано). В конечном итоге вызывается контроллер «home.class.php», в котором и происходит подключение компонента на страницу. В глобальном масштабе это выглядит так — формируется структура HTML страницы админки (секции head, body):

  • в head'e подключаются скрипты и стили, определяются важные системные параметры;
  • в body формируется интерфейс. Он состоит из двух частей.
    • дерево — располагается слева в элементе <div id="modx-leftbar"></div>;
    • контент компонента — находится справа в элементе <div id="modx-content"></div>.

Вот за формирование правой части интерфейса как раз и отвечает контроллер home.class.php. Он загружает скрипты компонента и подключает компонент на страницу.

Работа контроллера home.class.php

Вот скрипты подключения из контроллера home.class.php.

public function loadCustomCssJs() {
    $this->addCss($this->modExtra->config['cssUrl'] . 'mgr/main.css');
    $this->addCss($this->modExtra->config['cssUrl'] . 'mgr/bootstrap.buttons.css');
    $this->addJavascript($this->modExtra->config['jsUrl'] . 'mgr/modextra.js');
    $this->addJavascript($this->modExtra->config['jsUrl'] . 'mgr/misc/utils.js');
    $this->addJavascript($this->modExtra->config['jsUrl'] . 'mgr/misc/combo.js');
    $this->addJavascript($this->modExtra->config['jsUrl'] . 'mgr/widgets/items.grid.js');
    $this->addJavascript($this->modExtra->config['jsUrl'] . 'mgr/widgets/items.windows.js');
    $this->addJavascript($this->modExtra->config['jsUrl'] . 'mgr/widgets/home.panel.js');
    $this->addJavascript($this->modExtra->config['jsUrl'] . 'mgr/sections/home.js');
    $this->addHtml('<script type="text/javascript">
    Ext.onReady(function() {
        MODx.load({ xtype: "modextra-page-home"});
    });
    </script>
    ');
}

Само подключение на страницу происходит в последней строчке методом MODx.load(), который загружает компонент ExtJs, зарегистрированный как «modextra-page-home», когда страница отрендерена и DOM построен. Проще говоря, происходит что-то типа new Class(), где Class — это «modextra-page-home». А сам класс предварительно был определен и загружен в предыдущей строчке $this->addJavascript($this->modExtra->config['jsUrl'] . 'mgr/sections/home.js');.

Вот как выглядит этот файл:

modExtra.page.Home = function (config) {
	config = config || {};
	Ext.applyIf(config, {
		components: [{
			xtype: 'modextra-panel-home'
		}]
	});
	modExtra.page.Home.superclass.constructor.call(this, config);
};
Ext.extend(modExtra.page.Home, MODx.Component);
Ext.reg('modextra-page-home', modExtra.page.Home);

Те, кто знает ООП, глядя на этот код понимает, что тут у глобального объекта modExtra (который определяется в файле modextra.js), у свойства page определяется функция-конструктор Home, которая добавляет на страницу объект ExtJs с xtype'ом (проще говоря классом) «modextra-panel-home» с помощью метода _addComponents(), который был унаследован от MODx.Component. Этот метод добавляет все объекты, чьи xtype (классы) перечислены в свойстве components в правую часть страницы (в левую часть, как мы помним, загружается дерево объектов или элементов). В данном случае добавляется одна панель, в которую в свою очередь будут добавлены другие элементы компонента — панели, таблицы, формы и т.д.

Давайте теперь глянем на файл modextra.js

var modExtra = function (config) {
	config = config || {};
	modExtra.superclass.constructor.call(this, config);
};
Ext.extend(modExtra, Ext.Component, {
	page: {}, window: {}, grid: {}, tree: {}, panel: {}, combo: {}, config: {}, view: {}, utils: {}
});
Ext.reg('modextra', modExtra);

modExtra = new modExtra();

Тут все достаточно понятно. Определяется конструктор объекта modExtra. У него определяются свойства page, window и т.д., которые в свою очередь тоже являются объектами javascript. Таким образом, у modxExtra могут быть определены, например, несколько окон — modExtra.window.CreateItem и modExtra.window.UpdateItem. А в конце скрипта создается сам объект через new modExtra(). Он должен вызываться раньше все остальных скриптов компонента.

Хочу заметить, что в ExtJs используется 2 способа создания объектов — прямой и ленивый. Прямой — это когда объект создается непосредственно через конструкцию Ext.create(). А ленивый — через xtype. Этот пример мы уже видели выше.
// Первый способ
components: [{
	xtype: 'modextra-panel-home', 
}]
// Второй способ
Ext.create({
    xtype: 'panel',
    items: [
        new Extra.panel.Home()
    ]
});

Функция Ext.reg() нужна, чтобы зарегистрировать xtype для последующего ленивого создания.

Осталось разобраться с появлением таблиц и форм. Давайте вернемся к файлу home.js, в котором указывается объект ExtJs с xtype «modextra-panel-home». Это панель c закладками нашего компонента modExtra. Именно ее мы видим открывая приложение. Она определяется в файле home.panel.js. А в самой панели через свойства xtype подключаются нужные объекты — таблицы, формы и т.п.

Вот такая схема. Надеюсь, получилось понятно и для полезно для новичков.
10 сентября 2016, 12:24   968     0

Комментарии ()

    Вы должны авторизоваться, чтобы оставлять комментарии.

    Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.