[перевод] modExt по сравнению с ExtJS и документация по ним

Когда дело доходит до разработки компонентов MODx, наверное, ExtJS вызывает больше всего проблем. Его не обязательно использовать, но так как большинству людей хочется, чтобы их компоненты выглядели правильно, не остается выбора... Я надеюсь, этот пост в блоге прольет хотя бы каплю света на то, как взаимодействуют modExt и ExtJS и как использовать документацию по ExtJS API, чтобы понимать, что происходит. Да, я еще приведу некоторые примеры и трюки по работе с ExtJS.

Чем именно является modExt?

Если говорить по простому, то modExt тот же ExtJS, но с некоторыми дополнениями (расширениями) от команды MODx и с установленной по умолчанию темой админской части. Поскольку ExtJS - класс (или объект) основанный на JavaScript фреймворке, то modExt точно такой же класс. Важно помнить, что вы не ограниченны только реализацией modExt - нет, у вас есть все возможности фреймворка ExtJS. Некоторые части ExtJS были расширены (помните, что это объектно-ориентированный фреймворк? Да здравствует ООП!), чтобы обеспечить некоторую дополнительную функциональность. Эта расширенная функциональность доступна через переменную "MODx" в JavaScript, а все не переопределенные функции и классы доступны в через переменную "Ext".

Почему важно понимать, что modExt - это просто расширение?

Ну, если бы вы были как я, когда я впервые начал разбираться с компонентами, вы бы смотрели на документацию по modExt вечно и никогда бы не получили бы ничего полезного от этой информации. Какой смысл в ней, если там только списки (самое важное) расширенных классов - не все, что вы можете использовать!

Вот где кладезь знаний по ExtJS 3.4.0 API Docs. Ребята, он огромен! И если вы знаете где искать, то это определенно очень и очень ценно.

Давайте пробовать: возьмем bdListings в качестве примера

Чтобы понимать (я предполагаю, что если вы так далеко дочитали этот пост, вы по крайней мере работали с modExt/ExtJS немного и понимаете его синтаксис), вот пример Grid-а с использованием modExt-реализации ExtJS Grid, которую я буду терзать, чтобы показать различия между modExt и ExtJS. Посколько пример довольно длинный, я вырезал несколько кусков (обозначены как /* ... */), но вы можете увидеть полный исходный код на github, если хотите.

bdListings.grid.TargetGroups = function(config) {
    config = config || {};
    Ext.applyIf(config,{
        url: bdListings.config.connector_url,
        id: 'grid-targetgroups',
        baseParams: {
            action: 'mgr/targetgroups/getlist'
        },
        params: [],
        viewConfig: {
            forceFit: true,
            enableRowBody: true
        },
        tbar: [{
            xtype: 'button',
            text: _('bdlistings.create',{ what: _('bdlistings.target') } ),
            handler: function() {
                win = new bdListings.window.TargetGroups();
                win.show();
            }
        }],
        paging: true,
        primaryKey: 'id',
        remoteSort: true,
        sortBy: 'order',
        fields: [
            {name: 'id', type: 'int'},
            {name: 'name', type: 'string'},
            {name: 'sortorder', type: 'int'}
        ],
        columns: [{
            header: _('id'),
            dataIndex: 'id',
            sortable: true,
            width: 1,
            hidden: true
        },{
            /* ... */
        }]
    });
    bdListings.grid.TargetGroups.superclass.constructor.call(this,config);
};
Ext.extend(bdListings.grid.TargetGroups,MODx.grid.Grid,{
    getMenu: function() {
        var r = this.getSelectionModel().getSelected();
        var d = r.data;
 
        var m = [];
        m.push({
            text: _('bdlistings.update',{what: _('bdlistings.target')}),
            handler: function () {
                win = new bdListings.window.TargetGroups();
                win.setValues(d);
                win.show();
            }
        },'-',{
            /* ... */
        });
 
        if (m.length > 0) {
            this.addContextMenuItem(m);
        }
    }
});
Ext.reg('bdlistings-grid-targetgroups',bdListings.grid.TargetGroups);

То, что я хочу отметить в этом примере - части представленного modExt, а что на самом деле просто ExtJS. Я просто пройдусь по коду и выделю несколько важных вещей.

  • Строки 4, 6-9, 26-39. В оригинальном ExtJS, каждая сетка (Grid) имеет data store, который содержит описание данных и переменных. Так как компоненты MODx в большинстве случаев работают с AJAX коннекторами (обработчиками), которые возвращают JSON, вы получаете возможность создать экземпляр в хранилище без присваивания его вручную. Это работает через определение свойства "url" (которое в этом примере - значение bdListings.config.connector_url, указывающее на assets/components/bdlistings/connector.php который работает как наш коннектор). После определения свойства url мы также должны определить наше действие (мы можем это сделать как через baseParam так и через обычную опцию конфигурации - оба варианта рабочие), различные имена полей мы ждем (строки 26-30) и какие колонки мы хотим показывать (строки 31-39). Эти переменные используются для создания Ext.data.JsonStore, которое работает с массивом JSON, возвращаемым процессором. Вывод: эти свойства - контекст Ext.data.JsonStore, но если вы хотите, вы можете определить их вручную. Как это сделать вы найдете на всех форумах по Sencha и в документации.
  • Строки 16,50. Чтобы просто добавить интернационализацию (обычно сокращают как "i18n" от "начинается наi, затем 18 букв, и заканчивается на n"), вы заметите маленькую функцию со следующей сигнатурой:_('key',{arrayOf: 'options'}). Это JavaScript-функция доступная в админке MODx, которая проверяет загруженные словари для ключа, который вы указали. Если в строках есть плейсхолдеры, вы можете задать им значения с помошью второго параметра. Выводэто особенность MODX и вы не найдете этого в документации ExtJS и на форумах.
  • Строки 14-20: Несмотря на то, что панели управления (toolbars) (определяется как "tbar" или "bbar" для нижних панелей) не определены в modExt и они работают так же как ExtJS tbar configuration, бывают случаи, когда modExt дает некоторые бонусы. Например, при расширении MODx.tree.Tree вы увидите, что панель управления(toolbar) уже создана. Добавление чего-либо в конфигурацию tbar будет выполнено после него. Если вы не хотите использовать стандартные кнопки (развернуть, свернуть и обновить) вы можете установить свойство useDefaultToolbar в логическое false и тогда будет загружен только ваш собственный конфиг tbar. Все остальное наследуется от ExtJS. Выводработает так же как ExtJS, но в некоторых компонентах будет использоваться конфигурация по умолчанию.
  • Строка 43 показывает нам использование нашего собственного объекта bdLisings.grid.TargetGroups из объекта MODx.grid.Grid. Если мы посмотрим на документацию MODx.grid.Grid, первое, что мы увидим, будет информация о том, что он расширяет объект Ext.grid.EditorGridPanel (в свою очередь унаследованный от объекта Ext.grid.GridPanel), которая означаетw, что мы можем использовать все свойства и функции этого объекта с добавлением отдельных моментов из документации MODx.grid.Grid. Вывод: Чаще смотрите документацию по Ext.grid.EditorGridPanel!
  • Строки 44-63 по настоящему гениальны (а так же упомянутые в документации MODx.grid.Grid), и показывают контекстное меню при клике правой клавишей мышки без необходимости возиться с обработчиками "rowcontextmenu", позиционированием мыши и не только (мне понадобилось много времени на отладку!). В общем вы создаете новый массив (в ядре он обычно называется "m") и используете m.push() с параметрами конфигурации Ext.menu.Item для каждого элемента, который вы хотите добавить в меню. В конце концов вы можете (строки 60-62 в этом примере) вызвать метод addContextMenuItem компонента, или (для MODX 2.1 так работает) просто вернуть массив "m". В строке 56 тире будут преобразованы в тонкую границу между элементами меню. Обратите внимание, что вы можете получить доступ к пункту меню в сетке, вызванному правой клавишей мыши через "this.menu.record" в случае необходимости условного меню. Вывод: Это одно из расширений modExt, которое мне действительно нравится.

Я думаю, моя точка зрения будет понятна... используйте документацию по ExtJS 3.4! Теперь перейдем к следующему вопросу... как ее использовать?

Как работать с документацией по ExtJS

Документация по ExtJS огромна и действительно содержит ответы на все вопросы. Просто нужно правильно задать вопрос!

Для начала необходимо выяснить имя класса, который вы собираетесь использовать. Возможно, вы смотрите на чужой код, тогда проверте строки Ext.extend(). Возвращаясь к примеру с grid, мы видим что расширен MODx.grid.Grid, который в свою очередь расширяет Ext.grid.EditorGridPanel. Это то, что нам нужно! Откройте документацию по ExtJS и просто перемещайтесь по дереву вправо. Ext -> grid -> EditorGridPanel. Вы увидите несколько вещей:

  • Обычно описание того, что класс делает и несколько примеров. Схема наследования справа покажет от чего он наследуется.
  • Затем параметры конфигурации, с которыми вы и будете чаще всего работать. Они представлены обычно в виде списка возможных значений и значений по умолчанию, так же примеры кода.
  • Где-то ниже (в середине документации EditorGridPanel) вы найдете раздел Properties. Эти переменные доступны снаружи, когда вы ссылаетесь на объект. Например, "this" в зависимости от контекста или  "Ext.getCmp('id-of-my-grid')" из откуда-нибудь. Вы можете использовать это для проверки состояния или настроек объекта.
  • Дальше вы найдете описание методов, которые вы моете вызывать у объекта. Методы могут изменить настройки самого объекта (например addClass), или вернуть значение (например getPosition). Всякий раз, когда я ссылался на объект, мне нравилось отправлять его в консоль через console.log, что позволяло мне видеть список методов в Firebug, когда мне нужно было. (кажется, Dev Tools в Chrome не показывают имеющиеся методы).
  • Читаааая дальше вы найдете список событий. Они вызываются компонентом или его родителем и позволяют включиться в происходящее. Вверху перечислены события, там так же есть список параметров, который может быть передан в важу функциою обраного вызова (callback).

Таким образом это вся информация об объектах ExtJS, которая может вам понадобиться. Теперь разберемься с этим компонентом!

Заметка: Я знаю, что даже не приблизился ко всему, что вам необходимо знать, но я думаю, что это помогло бы мне раньше, когда я только начал, если бы кто-то указал бы мне на список событий и параметры конфигурации для объектов modExt...  Я использовал закладки, чтобы проверить, какие события всплывают в течение нескольких месяцев и вечно злоупотреблял console.log, но иметь на руках актуальный список - это изумительно! ;)

Да, еще кое-что о modExt...

Очень полезно знать, что modExt предлагает вам и какие настройки по умолчанию установлены, если вы расширяете объекты MODx. Вы можете найти все файлы modExt в /manager/assets/modext/. Так как файлов там достаточно много, я хотел бы подчеркнуть, что вы можете найти их в различных папках (относительно от папки /modext/):

  • core - содержит строительные блоки modExt. Сами объекты MODx в modx.js, сборщик расположения в modx.layout.js и базовые компоненты в modx.component.js. Не лучшее место для начала изучения modExt, скажу я вам.
  • sections - в терминологии, используемой командой MODx для ядра MODx и ряда расширений "секция" - это то, с чего начинается построение интерфейса, загрузка xtype и возможно установка переменных. Как по мне, не слишком интересно для разработки дополнений.
  • util - содержит несколько дополнительных xtypes/components, которые можно использовать, включая поле дата+время, lightbox и диалог загрузки ядра. Файл utilities.js также содержит сторонние (3rd) компоненты такие как superboxselect и некоторые другие маленькие утилитки. Иногда можно что-нибудь посмотреть.
  • widgets - это уже интереснее! Виджетом может быть все что угодно от панели, сетки (grid) или окна до отдельного списка. Основные объекты расположены в этой папке widgets/core, так что вы можете найти там определение MODx.grid.Grid, так же MODx.tree.Tree и MODx.Console, а так же многое другое. Все приложения в админке MODx лежат в папках внутри папки widgets, поэтому если вы видите что-либо в админке и хотите сделать похоже... скорее всего все лежит в папке widgets
  • workspace - рабочее пространство (workspace) является особенным, так как это виджеты и секции в одной папке, специфичные для рабочего пространства (в основном для Package Manager и всего, что с ним связано).

Не бойтесь смотреть исходники ядра или других компонентов!

Источник: http://www.markhamstra.com/modx-blog/2012/01/modext-versus-extjs-and-working-with-their-docs/

Автор: Mark Hamstra

Перевел: Иван Климчук


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

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

    © 2011 — 2014 MODX Беларусь
    По всем вопросам обращаться в компанию Alroniks Experts