Перейти к основному содержимому

5.01. Справочник по Ext JS

Разработчику Архитектору

Общая архитектура ExtJS

ExtJS — это полноценный JavaScript-фреймворк для создания сложных веб-приложений с богатым пользовательским интерфейсом. Он предоставляет систему компонентов, управление данными, маршрутизацию, шаблоны и инструменты разработки.

Ключевые принципы:

  • Все элементы интерфейса — экземпляры классов, наследуемых от Ext.Component.
  • Компоненты могут содержать другие компоненты через систему контейнеров (Ext.container.Container).
  • Управление жизненным циклом компонентов осуществляется через события: initComponent, afterRender, destroy.
  • Поддержка реактивности через связывание данных (bind) и MVVM-архитектуру.
  • Макеты (layout) определяют позиционирование и размеры дочерних элементов.

Базовый класс: Ext.Component

Все виджеты и контейнеры наследуются от Ext.Component.

Основные конфигурации:

КонфигТипОписаниеПримеры значений
idStringУникальный идентификатор компонента'mainPanel'
itemIdStringЛокальный идентификатор для поиска внутри контейнера'searchField'
clsStringCSS-класс, добавляемый к корневому элементу'custom-panel-style'
styleString / ObjectИнлайновые стили{ color: 'red', padding: '10px' }
hiddenBooleanСкрывает компонент без удаления из DOMtrue, false
disabledBooleanОтключает взаимодействие с компонентомtrue, false
renderToString / HTMLElementКонтейнер, в который рендерится компонент при создании'app-container', document.body
width / heightNumber / StringРазмеры компонента300, '100%'
minWidth / maxWidthNumberОграничения по ширине200, 800
flexNumberИспользуется в layout типа hbox или vbox1, 2
tooltipString / ObjectВсплывающая подсказка'Нажмите для сохранения'
uiStringТема оформления (если определена)'light', 'dark'

Основные методы:

  • show() — делает компонент видимым.
  • hide() — скрывает компонент.
  • enable() — включает компонент.
  • disable() — отключает компонент.
  • destroy() — удаляет компонент и освобождает ресурсы.
  • up([selector]) — ищет ближайший родительский компонент по селектору.
  • down([selector]) — ищет первый дочерний компонент по селектору.
  • query([selector]) — возвращает массив компонентов по селектору.

Селекторы для поиска:

  • По xtype: 'button'
  • По itemId: '#myButton'
  • По id: 'myButton' (без решётки)
  • По классу: '.my-class'
  • По атрибуту: '[text=Save]'

Контейнеры (Ext.container.Container и наследники)

Контейнеры управляют дочерними компонентами и применяют макеты.

Общие конфигурации контейнера:

КонфигТипОписание
itemsArray / ObjectМассив или одиночный компонент для отображения
layoutString / ObjectТип макета или его конфигурация
defaultsObjectКонфигурация по умолчанию для всех дочерних элементов
autoDestroyBooleanАвтоматическое уничтожение дочерних компонентов при удалении контейнера
scrollableBoolean / StringПолосы прокрутки

Основные типы контейнеров:

1. Ext.panel.Panel

Панель с заголовком, тулбаром, телом и футером.

Дополнительные конфигурации:

  • title — заголовок панели.
  • header — объект или false для скрытия заголовка.
  • tools — массив кнопок в правом верхнем углу (например, закрыть, свернуть).
  • tbar / bbar — верхний и нижний тулбары.
  • collapsible — возможность сворачивания.
  • collapsed — начальное состояние свёрнутости.
  • frame — рамка вокруг панели (стилизация).
  • bodyPadding — отступ внутри тела панели.

Пример tools:

tools: [{
type: 'close',
handler: function() { /* закрытие */ }
}]

2. Ext.window.Window

Модальное или немодальное окно поверх интерфейса.

Особенности:

  • Наследуется от Panel.
  • Поддерживает перетаскивание (draggable: true по умолчанию).
  • Может быть модальным (modal: true).
  • Имеет кнопки OK/Cancel через buttons или fbar.

Конфигурации:

  • modal — затемнение фона и блокировка взаимодействия.
  • closable — кнопка закрытия в заголовке.
  • resizable — возможность изменения размера.
  • constrain — ограничение перемещения в пределах viewport.
  • animateTarget — элемент, от которого анимируется появление.

3. Ext.tab.Panel

Контейнер с вкладками.

Конфигурации:

  • tabPosition — положение вкладок: 'top', 'bottom', 'left', 'right'.
  • activeTab — индекс или ссылка на активную вкладку.
  • plain — упрощённый стиль без рамок.
  • deferredRender — отложенная отрисовка невидимых вкладок.

У вкладки (дочернего компонента):

  • title — название вкладки.
  • iconCls — CSS-класс иконки.
  • closable — кнопка закрытия вкладки.

4. Ext.container.Viewport

Контейнер, занимающий всё окно браузера. Автоматически рендерится в document.body.

  • Не требует renderTo.
  • Реагирует на изменение размера окна.

Макеты (layout)

Макеты управляют расположением и размерами дочерних компонентов.

Основные типы макетов:

fit

  • Отображает один дочерний компонент, растягивая его на всю площадь контейнера.
  • Используется в модальных окнах, карточках.

hbox / vbox

  • Горизонтальное (hbox) или вертикальное (vbox) выравнивание.
  • Поддерживает align, pack, flex.

Конфигурации:

  • align — выравнивание по поперечной оси: 'start', 'center', 'stretch', 'end'.
  • pack — распределение по главной оси: 'start', 'center', 'end', 'justify'.
  • flex — пропорциональное распределение пространства.

Пример:

layout: {
type: 'hbox',
align: 'stretch',
pack: 'center'
}

border

  • Делит контейнер на регионы: north, south, west, east, center.
  • Только один дочерний элемент может иметь region: 'center'.
  • Элементы с region: 'west' или 'east' могут быть сворачиваемыми (collapsible: true).

card

  • Отображает один "карточный" элемент за раз.
  • Переключение через setActiveItem().

anchor

  • Позволяет задавать размеры относительно родителя с помощью anchor у дочерних элементов.
  • Пример: anchor: '100% 50%' — ширина 100%, высота 50%.

table

  • Располагает элементы в сетке, как HTML-таблица.
  • Использует columns и tdAttrs.

Формы и поля ввода (Ext.form.*)

Формы в ExtJS строятся на базе Ext.form.Panel, который автоматически управляет сбором, валидацией и отправкой данных.

Базовый класс: Ext.form.field.Base

Все поля наследуются от этого класса и поддерживают общие свойства:

КонфигТипОписаниеПримеры
fieldLabelStringПодпись к полю'Имя пользователя'
nameStringИмя поля для отправки данных'username'
valueAnyНачальное значение'admin'
allowBlankBooleanРазрешает пустое значениеfalse
blankTextStringСообщение при пустом значении'Поле обязательно'
validatorFunctionПользовательская функция валидацииfunction(val) { return val.length > 3 ? true : 'Минимум 4 символа'; }
validateOnBlurBooleanЗапускать валидацию при потере фокусаtrue
validateOnChangeBooleanВалидация при каждом измененииtrue
msgTargetStringГде отображать ошибку'side', 'under', 'qtip'
inputAttrTplStringШаблон атрибутов HTML-элемента'<tpl if="required">required</tpl>'

Основные типы полей:

Ext.form.field.Text

  • Однострочное текстовое поле.
  • Дополнительные конфиги: emptyText, maxLength, enforceMaxLength.

Ext.form.field.TextArea

  • Многострочное поле.
  • Поддерживает grow (автоматическое расширение по высоте).

Ext.form.field.Number

  • Только числа.
  • Конфиги: minValue, maxValue, decimalPrecision, step.

Ext.form.field.Date

  • Выбор даты через календарь.
  • format — формат отображения ('d.m.Y').
  • submitFormat — формат при отправке.

Ext.form.field.ComboBox

  • Выпадающий список с возможностью ввода.
  • Связывается с Ext.data.Store.
  • Ключевые конфиги:
    • displayField — поле для отображения.
    • valueField — поле для значения.
    • queryMode'local' или 'remote'.
    • typeAhead — автозавершение.
    • forceSelection — разрешает только выбор из списка.
    • editable — можно ли вводить текст.

Ext.form.field.Checkbox / Ext.form.field.Radio

  • Чекбоксы и радиокнопки.
  • Группировка радио через name.

Ext.form.field.File

  • Выбор файла.
  • Поддержка multiple: true.
  • Не отправляет данные напрямую — требует FormData или iframe в старых версиях.

Ext.form.FieldContainer

  • Контейнер для группировки полей без визуального поля ввода.
  • Полезен для кастомных компонентов (например, «Диапазон дат» из двух полей).

Таблицы: Ext.grid.Panel

Один из самых мощных компонентов ExtJS — грид для отображения табличных данных.

Основные конфигурации:

КонфигОписание
storeЭкземпляр Ext.data.Store с данными
columnsМассив описаний колонок
selModelМодель выделения: 'rowmodel', 'cellmodel', 'checkboxmodel'
pluginsРасширения: редактирование, drag-and-drop
viewConfigНастройки отрисовки строк
enableColumnHideРазрешить скрывать колонки через меню
enableColumnMoveРазрешить перетаскивание колонок
enableColumnResizeИзменение ширины колонок
columnLinesВертикальные линии между колонками
rowLinesГоризонтальные линии между строками

Колонки (columns):

Каждая колонка — объект с конфигурацией.

СвойствоОписание
textЗаголовок колонки
dataIndexИмя поля в модели данных
widthШирина в пикселях
flexПропорциональная ширина
sortableСортировка по клику
rendererФункция для кастомного отображения ячейки
editorПоле для inline-редактирования
hiddenСкрыта ли колонка
menuDisabledОтключено ли контекстное меню колонки

Пример колонки:

{
text: 'Статус',
dataIndex: 'status',
renderer: function(value) {
return value === 1 ? 'Активен' : 'Неактивен';
},
editor: {
xtype: 'combobox',
store: statusStore,
displayField: 'name',
valueField: 'id'
}
}

Редактирование в гриде:

  • Включается через плагин cellediting или rowediting.
  • При двойном клике или нажатии Enter открывается редактор.
  • Поддерживает все стандартные поля ввода.

Панели инструментов грида:

  • dockedItems с xtype: 'pagingtoolbar' — пагинация.
  • topBar / bottomBar — кастомные панели.

Деревья: Ext.tree.Panel

Используется для иерархических данных.

Особенности:

  • Хранит данные в Ext.data.TreeStore.
  • Каждый узел — экземпляр Ext.data.Model с полями: text, leaf, expanded, children.
  • Поддерживает lazy-loading через proxy.

Конфигурации:

  • rootVisible — показывать корневой узел.
  • useArrows — использовать стрелки вместо +/-.
  • lines — отображать соединительные линии.
  • singleExpand — раскрывать только одну ветку за раз.

События:

  • itemclick, itemdblclick
  • beforeitemexpand, itemexpand
  • checkchange — при использовании чекбоксов (checked: true в узле)

Диаграммы и графики: Ext.chart.CartesianChart, Ext.chart.PolarChart

ExtJS включает встроенный движок визуализации на основе SVG/VML.

Типы диаграмм:

  • Линейная (line)
  • Столбчатая (bar, column)
  • Круговая (pie)
  • Радар (radar)
  • Площадная (area)

Основные компоненты диаграммы:

  • axes — оси X и Y (или радиальная/угловая для Polar)
  • series — наборы данных
  • legend — легенда
  • interactions — взаимодействия: zoom, pan, tooltip

Пример серии:

series: [{
type: 'line',
xField: 'month',
yField: 'sales',
title: 'Продажи',
marker: { radius: 4 }
}]

Особенности:

  • Поддержка анимации.
  • Адаптивность под размер контейнера.
  • Экспорт в изображение (через chart.save() в новых версиях).

🔹 Система данных: Ext.data.*

ExtJS предоставляет мощную систему управления данными через модели, хранилища и прокси.

1. Модель (Ext.data.Model)

Модель описывает структуру одной записи (например, пользователя, товара).

Основные конфигурации:

КонфигТипОписание
fieldsArrayОписание полей записи
idPropertyStringИмя поля, используемого как уникальный идентификатор
validatorsObjectПравила валидации полей
proxyObject / StringПрокси для загрузки/сохранения
hasMany / belongsToObjectОтношения «один ко многим», «многие к одному»

Пример модели:

Ext.define('App.model.User', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' },
{ name: 'email', type: 'string' },
{ name: 'active', type: 'boolean', defaultValue: true }
],
idProperty: 'id'
});

Типы полей:

  • 'string'
  • 'int'
  • 'float'
  • 'boolean'
  • 'date' — с опциональным dateFormat
  • 'auto' — без преобразования

Валидация:

validators: {
email: 'email',
name: { type: 'length', min: 2 }
}

2. Хранилище (Ext.data.Store)

Хранилище управляет коллекцией моделей.

Основные конфигурации:

КонфигОписание
modelКласс модели
dataНачальные данные (массив объектов)
proxyПрокси для загрузки/сохранения
autoLoadЗагружать данные автоматически при создании
pageSizeРазмер страницы для пагинации
remoteSortСортировка на сервере
remoteFilterФильтрация на сервере
sortersМассив правил сортировки
filtersМассив фильтров

Пример хранилища:

Ext.create('Ext.data.Store', {
model: 'App.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/api/users',
reader: { type: 'json', rootProperty: 'data' }
}
});

Методы хранилища:

  • load() — загрузка данных
  • reload() — повторная загрузка с теми же параметрами
  • sync() — отправка изменений на сервер
  • add(record) — добавление записи
  • remove(record) — удаление
  • findExact(field, value) — поиск по точному совпадению
  • filter(filters) — применение фильтров
  • clearFilter() — сброс фильтров

3. Прокси (Ext.data.proxy.*)

Прокси определяют, откуда и как загружаются/сохраняются данные.

Основные типы:

  • ajax — HTTP-запросы (GET/POST)
  • rest — RESTful API с методами GET/POST/PUT/DELETE
  • memory — данные хранятся в памяти
  • localstorage — сохранение в localStorage браузера
  • sessionstorage — сохранение в sessionStorage

Конфигурация прокси:

proxy: {
type: 'rest',
url: '/api/users',
reader: {
type: 'json',
rootProperty: 'items',
totalProperty: 'total'
},
writer: {
type: 'json',
writeAllFields: true
}
}

4. Читатели и записыватели (reader, writer)

Reader:

  • json — парсинг JSON
  • xml — парсинг XML
  • array — массивы

Ключевые свойства:

  • rootProperty — путь к массиву данных
  • totalProperty — общее количество записей (для пагинации)
  • successProperty — поле, указывающее на успех операции

Writer:

  • json — отправка данных в формате JSON
  • form — отправка как application/x-www-form-urlencoded

Ключевые свойства:

  • writeAllFields — отправлять все поля, даже неизменённые
  • allowSingle — разрешить отправку одиночной записи без массива

События (Events)

ExtJS использует систему событий на основе Ext.util.Observable.

Основные принципы:

  • Все компоненты и хранилища наследуют систему событий.
  • Подписка через on() или listeners.
  • Возможность отмены действия через return false в обработчике (если событие отменяемое).

Распространённые события компонентов:

  • click, dblclick
  • beforedestroy, destroy
  • show, hide
  • resize
  • afterrender

События формы:

  • validitychange — изменение состояния валидности
  • fieldvaliditychange

События грида:

  • itemclick, itemdblclick
  • selectionchange
  • edit — завершение редактирования ячейки
  • beforeedit — возможность отменить редактирование

События хранилища:

  • load — после загрузки данных
  • beforeload — до запроса
  • update — изменение записи
  • add, remove
  • write — после успешной отправки на сервер

Глобальные события:

  • Ext.onReady() — выполнение кода после загрузки DOM и фреймворка
  • Ext.getBody().on(...) — работа с DOM-событиями

Архитектура приложения: MVC и MVVM

MVC (Model-View-Controller)

  • Model — данные (Ext.data.Model)
  • View — компоненты интерфейса
  • Controller — логика, обработка событий

Контроллер регистрирует слушателей через control:

control: {
'button[action=save]': { click: 'onSaveClick' }
}

MVVM (Model-View-ViewModel)

  • Вводит ViewModel — контейнер данных, привязанных к View.
  • Поддерживает двустороннее связывание (bind).

Пример:

{
xtype: 'textfield',
bind: '{user.name}'
}

В контроллере или представлении:

viewModel: {
data: {
user: { name: 'John' }
}
}

Изменение user.name автоматически обновляет поле, и наоборот.


Утилиты и вспомогательные классы

Ext.Array

  • each(array, fn)
  • contains(array, item)
  • remove(array, item)
  • merge(arr1, arr2)

Ext.Object

  • toArray(obj)
  • getKey(obj, value)
  • isEmpty(obj)

Ext.String

  • format('Hello {0}', 'World')
  • escapeRegex(str)
  • capitalize(str)

Ext.Date

  • parse(dateString, format)
  • format(date, format)
  • add(date, interval, amount)

Ext.Function

  • defer(fn, delay, scope, args)
  • createBuffered(fn, buffer, scope)

Инструменты разработчика

Sencha Cmd

  • Командная строка для сборки, минификации, темизации.
  • Генерация приложений, контроллеров, моделей.
  • Поддержка тем через SASS.

DevTools Integration

  • Расширение Sencha Inspector для Chrome — позволяет:
    • Просматривать дерево компонентов
    • Анализировать хранилища
    • Отслеживать события
    • Изменять свойства в реальном времени

Отладка

  • console.log(component.up()) — исследование иерархии
  • component.el.dom — доступ к DOM-элементу
  • store.getRange() — просмотр текущих записей

Темы и стилизация

  • ExtJS использует Sass для тем.

  • Базовые темы: theme-classic, theme-neptune, theme-triton, theme-material.

  • Кастомизация через переопределение переменных:

    $panel-header-background-color: #333;
    $button-default-ui-background-color: #007bff;
  • Каждый компонент поддерживает ui-конфигурацию для переключения стилей:

    { xtype: 'button', text: 'Primary', ui: 'primary' }

Drag-and-Drop (DnD)

ExtJS включает встроенную поддержку перетаскивания через Ext.dd.*.

Основные компоненты:

  • Ext.dd.DragSource — элемент, который можно перетаскивать.
  • Ext.dd.DropTarget — область, в которую можно сбросить.
  • Ext.grid.plugin.DragDrop — плагин для грида, позволяющий перетаскивать строки.

Пример для грида:

plugins: {
ptype: 'gridviewdragdrop',
dragGroup: 'myGroup',
dropGroup: 'myGroup'
}

События DnD:

  • beforedrop — возможность отменить сброс.
  • drop — обработка успешного сброса.
  • dragstart, dragover, dragend

Кастомный DnD:

Для произвольных элементов используется Ext.dd.DD или Ext.dd.DDProxy.


Шаблоны: Ext.XTemplate

Позволяют гибко формировать HTML на основе данных.

Возможности:

  • Условия (<tpl if="...">)
  • Циклы (<tpl for=".">)
  • Форматирование через функции
  • Поддержка массивов и вложенных объектов

Пример:

var tpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="user {active: "active" : "inactive"}">',
'<h3>{name}</h3>',
'<p>Email: {[this.formatEmail(values.email)]}</p>',
'</div>',
'</tpl>',
{
formatEmail: function(email) {
return email ? email.toLowerCase() : '—';
}
}
);

Использование:

  • В Ext.view.View (DataView)
  • В renderer колонок грида
  • В tpl свойстве компонентов

Создание кастомных компонентов

Расширение существующих компонентов — основной способ кастомизации.

Базовый шаблон:

Ext.define('MyApp.view.CustomButton', {
extend: 'Ext.button.Button',
xtype: 'custombutton',

config: {
customColor: '#000'
},

applyCustomColor: function(color) {
this.el.setStyle('color', color);
return color;
},

initialize: function() {
this.callParent();
// Дополнительная инициализация
}
});

Рекомендации:

  • Использовать xtype для регистрации.
  • Разделять логику и представление.
  • Использовать config для управляемых свойств с геттерами/сеттерами.
  • Вызывать callParent() при переопределении методов.

Производительность

Оптимизация гридов:

  • Использовать bufferedRenderer: true для больших наборов данных.
  • Ограничивать количество отображаемых колонок.
  • Избегать сложных renderer в каждой ячейке.
  • Использовать rowexpander вместо вложенных гридов, если возможно.

Оптимизация форм:

  • Группировать поля в FieldSet только при необходимости.
  • Откладывать создание невидимых вкладок (deferredRender: true).

Общие практики:

  • Минимизировать количество DOM-элементов.
  • Уничтожать неиспользуемые компоненты (destroy()).
  • Использовать itemId вместо id для локального поиска.
  • Избегать глубоких вложенности контейнеров.

Тестирование

Подходы:

  • Unit-тесты: Jasmine + Karma (через Sencha Cmd).
  • Интеграционные тесты: Siesta (официальный инструмент Sencha).
  • Ручное тестирование: через DevTools и Sencha Inspector.

Советы:

  • Тестируйте хранилища отдельно от UI.
  • Мокайте прокси для изоляции данных.
  • Проверяйте состояние компонентов после событий.

Полный список xtype

xtypeКласс
componentExt.Component
containerExt.container.Container
panelExt.panel.Panel
windowExt.window.Window
formExt.form.Panel
fieldsetExt.form.FieldSet
textfieldExt.form.field.Text
textareaExt.form.field.TextArea
numberfieldExt.form.field.Number
datefieldExt.form.field.Date
timefieldExt.form.field.Time
checkboxExt.form.field.Checkbox
radioExt.form.field.Radio
comboboxExt.form.field.ComboBox
filefieldExt.form.field.File
displayfieldExt.form.field.Display
buttonExt.button.Button
splitbuttonExt.button.Split
cycleExt.button.Cycle
gridExt.grid.Panel
treeExt.tree.Panel
dataviewExt.view.View
tabpanelExt.tab.Panel
viewportExt.container.Viewport
toolbarExt.toolbar.Toolbar
pagingtoolbarExt.toolbar.Paging
menubarExt.menu.Bar
menuExt.menu.Menu
colorpickerExt.picker.Color
datepickerExt.picker.Date
sliderExt.slider.Single
multisliderExt.slider.Multi
chartExt.chart.CartesianChart
polarExt.chart.PolarChart

Полный список доступен в официальной документации ExtJS 7.0 Classic Toolkit.


Поддержка браузеров (ExtJS 7.x Classic)

БраузерПоддержка
ChromeПолная
FirefoxПолная
SafariПолная (macOS/iOS)
Edge (Chromium)Полная
Edge (Legacy)Не поддерживается
Internet ExplorerIE11 (только в Classic Toolkit)

Modern Toolkit не поддерживает IE11.


Лицензирование

  • GPLv3 — для открытых проектов.
  • Коммерческая лицензия — для проприетарного ПО.
  • Ext Core — MIT-лицензия (устаревшая часть, не используется в новых версиях).

Использование ExtJS в коммерческом продукте без лицензии нарушает условия Sencha.