Ext JS
Ext JS
Что такое Ext JS?
Ext JS — это Р·СЂРµР"ый JavaScript-фреймворк высокого СѓСЂРѕРІРЅСЏ, предназначенный РґР"СЏ разработки масштабных, богатых РїРѕ функционаР"ьности веб-РїСЂРёР"ожений СЃ ориентацией РЅР° корпоративный сегмент. РћРЅ РѕС‚Р"ичается РЅРµ просто богатым набором РїРѕР"ьзоватеР"СЊСЃРєРёС… интерфейсов, РЅРѕ Рё продуманной архитектурой, РїРѕР·РІРѕР"яющей строить РїСЂРёР"ожения, сравнимые РїРѕ СЃР"ожности, структуре Рё предсказуемости поведения СЃ настоР"ьными РїСЂРёР"ожениями. Р’ РѕС‚Р"ичие РѕС‚ Р"ёгких Р±РёР±Р"иотек РІСЂРѕРґРµ jQuery UI РёР"Рё Bootstrap-компонентов, Ext JS решает задачу цеР"остной инфраструктуры РґР"СЏ front-end-разработки: РѕС‚ описания данных Рё РёС… РїСЂРёРІСЏР·РєРё Рє интерфейсу — РґРѕ управР"ения жизненным цикР"РѕРј РїСЂРёР"ожения, маршрутизации, Р"РѕРєР°Р"изации, темизации Рё инструментов СЃР±РѕСЂРєРё.
С чего начать чтение этой статьи
Чтобы материаР" РІРѕСЃРїСЂРёРЅРёРјР°Р"СЃСЏ Р"егче, СѓРґРѕР±РЅРѕ идти РІ таком РїРѕСЂСЏРґРєРµ:
- "Первая программа" — увидеть рабочий резуР"ьтат Рё структуру проекта.
- "Архитектурные основы" — понять, как устроены компоненты и данные.
- "Работа СЃ данными" Рё "Рнструменты разработки" — выйти РЅР° практику.
ЕсР"Рё РІС‹ выбираете стек СЃ РЅСѓР"СЏ, сравните РїРѕРґС…РѕРґС‹ СЃ Angular, React Рё Vue: там меньше РїРѕСЂРѕРі РІС…РѕРґР°, РЅРѕ Рё меньше "enterprise РёР· РєРѕСЂРѕР±РєРё".
Кому и когда стоит изучать Ext JS
- ЕсР"Рё поддерживаете legacy enterprise-систему, Ext JS стоит изучать РІ первую очередь.
- ЕсР"Рё запускаете новый проект СЃ РЅСѓР"СЏ, сначаР"Р° сравните стоимость поддержки СЃ Angular, React Рё Vue.
- РњРёРЅРёРјР°Р"ьный практический путь: поднять шабР"онный проект, СЃРґРµР"ать форму + РіСЂРёРґ + сохранение через proxy.
Разработка РЅР° Ext JS подразумевает принятие опредеР"ённой парадигмы — декР"аративное описание интерфейса, строгая типизация посредством метаданных, центраР"изованное управР"ение состоянием Рё событиями, Р° также единый РїРѕРґС…РѕРґ Рє совместимости Рё производитеР"ьности. Рто РґРµР"ает его особенно ценным РІ контексте РґР"итеР"ьных проектов СЃ Р±РѕР"ьшими командами, РіРґРµ важны предсказуемость, сопровождаемость Рё соответствие корпоративным стандартам.
Ext JS — это РїРѕР"ноценный фронтенд-фреймворк СЃ собственным языком описания структур, механизмом насР"едования, системой событий, встроенными абстракциями РґР"СЏ работы СЃ данными Рё инструментами РґР"СЏ разработки Рё развёртывания. Его РєР"ючевая идея — отдеР"ение описания интерфейса Рё Р"РѕРіРёРєРё РѕС‚ реаР"изации РІРёР·СѓР°Р"СЊРЅРѕРіРѕ представР"ения Рё взаимодействия. Разработчик описывает "что РґРѕР"Р¶РЅРѕ быть", Р° фреймворк отвечает Р·Р° "как это СЃРґРµР"ать" СЃ учётом кроссбраузерности, доступности, производитеР"ьности Рё СЃРѕРіР"асованности.
Фреймворк строится РЅР° принципах объектно-ориентированного программирования Рё шабР"РѕРЅРѕРІ проектирования, адаптированных Рє среде JavaScript. Р’ Ext JS РІСЃС‘ — объект — компонент, контейнер, РјРѕРґРµР"СЊ данных, храниР"ище, РїСЂРѕРєСЃРё-адаптер РґР"СЏ передачи данных, событие, даже конфигурация темы. Каждый объект имеет строгий жизненный цикР" — инициаР"изация, рендеринг, уничтожение — Рё сопровождается соответствующими событиями, РЅР° которые РјРѕР¶РЅРѕ подписаться. Рто РїРѕР·РІРѕР"яет выстраивать чёткую иерархию ответственности Рё избегать "спагетти-РєРѕРґР°" даже РІ очень Р±РѕР"ьших РїСЂРёР"ожениях.
Ext JS РЅРµ заменяет HTML/CSS/JavaScript, РЅРѕ ограничивает Рё канаР"изирует РёС… РёСЃРїРѕР"ьзование — разработчик редко работает напрямую СЃ DOM-СЌР"ементами, РЅРµ пишет обработчики onclick, РЅРµ управР"яет display: none вручную. Вместо этого РѕРЅ оперирует абстракциями, гарантирующими корректное поведение РЅР° всех поддерживаемых РїР"атформах.
Первая программа на Ext JS
Пошаговый запуск (Sencha Cmd, npm-реестр, шабР"РѕРЅ universalmodern) вынесен РІ отдеР"СЊРЅСѓСЋ статью — Первая программа РЅР° Ext JS.
Кратко: нужны Node.js, аккаунт Sencha, sencha --version, затем npm create @sencha/app@latest … и npm start.
Рстория развития
Рстоки Ext JS РІРѕСЃС…РѕРґСЏС‚ Рє 2006 РіРѕРґСѓ, РєРѕРіРґР° Джек РЎР"окам (Jack Slocum), работая РІ СѓСЃР"РѕРІРёСЏС… ограниченной выразитеР"ьности тогдашних веб-техноР"РѕРіРёР№, СЃРѕР·РґР°Р" расширение РґР"СЏ Yahoo! UI Library (YUI), названное YUI-Ext. ЦеР"СЊ Р±С‹Р"Р° проста — добавить РІ YUI недостающие компоненты — РІ первую очередь, решётку (grid) СЃ сортировкой, фиР"ьтрацией Рё редактированием, Р° также СѓР"учшенные оконные Рё панеР"ьные СЌР"ементы. YUI-Ext быстро стаР" РїРѕРїСѓР"ярным Р±Р"агодаря высокому качеству реаР"изации Рё вниманию Рє детаР"СЏРј — РїР"авной анимации, РіРёР±РєРѕРјСѓ управР"ению размерами, интуитивному поведению.
Р’ 2007 РіРѕРґСѓ Slocum РїСЂРёРЅСЏР" решение выдеР"ить проект РІ самостоятеР"СЊРЅСѓСЋ Р±РёР±Р"иотеку РїРѕРґ названием Ext JS. Рто Р±С‹Р"Р° самодостаточная система, которая РјРѕРіР"Р° РёСЃРїРѕР"ьзовать YUI Р"ишь как опционаР"СЊРЅСѓСЋ базу, Р° СЃРѕ временем РїРѕР"ностью РѕС‚ неё отказаР"ась. Версии 1.x Рё 2.x закрепиР"Рё репутацию Ext JS как Р±РёР±Р"иотеки "РґР"СЏ серьёзных РїСЂРёР"ожений" — РІ РѕС‚Р"ичие РѕС‚ jQuery, ориентированной РЅР° Р"егковесные интерактивные страницы, Ext JS изначаР"СЊРЅРѕ позиционироваР"СЃСЏ как инструмент РґР"СЏ РїСЂРёРєР"адного РџРћ РІ браузере.
ПереР"омный момент произошёР" РІ 2010 РіРѕРґСѓ, РєРѕРіРґР° компания Jazva, РІР"адевшая Ext JS, объединиР"ась СЃ Ext JS Labs (РіРґРµ работаР" РЎР"окам) Рё Sencha Touch (проектом РґР"СЏ РјРѕР±РёР"СЊРЅРѕР№ разработки) РІ единую компанию — Sencha Inc. РџРѕРґ этим брендом начаР"ась новая СЌРїРѕС…Р° — Ext JS стаР" частью единой экосистемы, РІРєР"ючающей инструменты разработки, системы СЃР±РѕСЂРєРё, РѕР±Р"ачные сервисы Рё коммерческую поддержку. Версии 3.x Рё 4.x (2010–2012) принесР"Рё масштабную реорганизацию архитектуры: переход РѕС‚ прототипного насР"едования Рє собственной системе РєР"ассов СЃ поддержкой РјРёРєСЃРёРЅРѕРІ, введение РјРѕРґРµР"Рё MVC, РїРѕР"РЅСѓСЋ переписку сетки Рё систему темизации через Sass.
Начиная СЃ Ext JS 5 (2014), фреймворк РїРѕР"учиР" поддержку единой РєРѕРґРѕРІРѕР№ базы РґР"СЏ десктопа Рё РјРѕР±РёР"ьных устройств, Р° РІ Ext JS 6 (2015) эта конвергенция Р±С‹Р"Р° доведена РґРѕ Р"огического завершения — РѕРґРЅР° Рё та Р¶Рµ РјРѕРґРµР"СЊ, РѕРґРёРЅ Рё тот Р¶Рµ контроР"Р"ер, РѕРґРёРЅ роутер — РЅРѕ разные представР"ения РІ зависимости РѕС‚ РїР"атформы (РєР"ассическая десктопная тема Neptune Рё РјРѕР±РёР"ьная тема Triton).
Р’ 2020 РіРѕРґСѓ Sencha Р±С‹Р"Р° приобретена компанией Idera, что РїРѕРІР"екР"Рѕ Р·Р° СЃРѕР±РѕР№ изменение Р"ицензионной РїРѕР"итики Рё замедР"ение темпов открытой разработки. Однако сообщество остаР"РѕСЃСЊ активным, Рё СЃ 2021 РіРѕРґР° разработка Ext JS частично РїСЂРѕРґРѕР"жается РІ рамках проекта ExtWebComponents Рё открытых форков (например, ExtAngular, ExtReact — адаптации Ext-компонентов РїРѕРґ современные фреймворки через Web Components). РџСЂРё этом РєР"ассический Ext JS РїСЂРѕРґРѕР"жает поддерживаться Рё РёСЃРїРѕР"ьзуется РІ тысячах корпоративных систем РїРѕ всему РјРёСЂСѓ.
Архитектурные основы
Р’ РѕСЃРЅРѕРІРµ Ext JS Р"ежит компонентная РјРѕРґРµР"СЊ, РіРґРµ каждый СЌР"емент интерфейса СЏРІР"яется экземпР"СЏСЂРѕРј РєР"асса Ext.Component РёР"Рё его насР"едника. Компонент — это РјРёРЅРёРјР°Р"ьная единица, РѕР±Р"адающая собственным DOM-представР"ением, состоянием, поведением Рё жизненным цикР"РѕРј. Простейший компонент может быть просто надписью (Ext.Component СЃ html — 'Привет'), Р° СЃР"ожнейший — многооконным РїСЂРёР"ожением СЃ РІР"оженными панеР"СЏРјРё, сетками, инструментами Рё внутренней маршрутизацией.
Компоненты организуются РІ иерархию РїРѕ принципу "контейнер–потомок". РљР"асс Ext.Container (Рё его потомки — Panel, Window, Viewport, TabPanel Рё РґСЂ.) может содержать РґСЂСѓРіРёРµ компоненты. РџСЂРё добавР"ении компонента РІ контейнер автоматически строится дерево РІР"адения: контейнер становится родитеР"ем, РІР"оженный СЌР"емент — потомком. Рта структура управР"яет РІРёР·СѓР°Р"ьным распоР"ожением Рё жизненным цикР"РѕРј: РїСЂРё уничтожении контейнера РІСЃРµ его потомки уничтожаются рекурсивно, что РёСЃРєР"ючает утечки памяти.
РљР"ючевым СЌР"ементом управР"ения РєРѕРјРїРѕРЅРѕРІРєРѕР№ СЏРІР"яется система макетов (layouts). Макет опредеР"яет как Рё РіРґРµ Р±СѓРґСѓС‚ размещены дочерние компоненты внутри контейнера. Р’ РѕС‚Р"ичие РѕС‚ CSS Flexbox РёР"Рё Grid, макеты Ext JS — это активные JavaScript-объекты, которые пересчитывают размеры Рё позиции РІ ответ РЅР° события — изменение размера РѕРєРЅР°, программное скрытие/показ СЌР"емента, РѕР±РЅРѕРІР"ение данных. Существуют как простые макеты (hbox, vbox, fit, card), так Рё СЃР"ожные (column, table, anchor, border). Например, макет border РїРѕР·РІРѕР"яет строить РєР"ассические трёхпанеР"ьные интерфейсы (север-центр-СЋРі, запад-центр-восток) без единой строки CSS.
Каждый компонент РїРѕР"учает СѓРЅРёРєР°Р"ьный itemId, иерархический id, Рё может быть найден РІ дереве через up(), down(), query(). Рто обеспечивает устойчивую навигацию РїРѕ структуре даже РїСЂРё динамическом изменении содержимого — критически важно РґР"СЏ Р±РѕР"ьших РїСЂРёР"ожений.
Архитектурные паттерны
Начиная СЃ версии 4, Ext JS официаР"СЊРЅРѕ поддерживает РґРІР° основных РїРѕРґС…РѕРґР° Рє организации РєРѕРґР°: MVC (Model–View–Controller) Рё MVVM (Model–View–ViewModel). РћР±Р° паттерна внедрены как встроенные, строго типизированные механизмы фреймворка, СЃ обязатеР"ьными СЃРѕРіР"ашениями Рѕ именовании, автоматической загрузкой РєР"ассов Рё управР"ением СЃРІСЏР·СЏРјРё.
Р’ MVC РїСЂРёР"ожение раздеР"яется РЅР° три СЃР"РѕСЏ.
— РњРѕРґРµР"СЊ (Ext.Data.Model) описывает структуру данных — РїРѕР"СЏ, РёС… типы, РІР°Р"идации, зависимости.
— ПредставР"ение (view) — это иерархия компонентов, обычно РѕР±СЉСЏРІР"енная как РєР"асс, насР"едующий РѕС‚ Ext.Component РёР"Рё Ext.Container. ПредставР"ение РЅРµ содержит бизнес-Р"РѕРіРёРєРё Рё РЅРµ обращается напрямую Рє данным.
— КонтроР"Р"ер (Ext.app.Controller) связывает события представР"ения (например, РєР"РёРє РїРѕ РєРЅРѕРїРєРµ) СЃ действиями над РјРѕРґРµР"СЊСЋ Рё храниР"ищем, Р° также реагирует РЅР° изменения данных, инициируя РѕР±РЅРѕРІР"ение интерфейса. КонтроР"Р"ер РЅРµ управР"яет DOM — РѕРЅ управР"яет состоянием Рё потоком событий.
РЎРІСЏР·РєР° между представР"ением Рё контроР"Р"ером обеспечивается через СЃРµР"екторы — синтаксис, РїРѕС…РѕР¶РёР№ РЅР° CSS-СЃРµР"екторы, РЅРѕ работающий СЃ itemId, xtype, иерархией компонентов. Например, запись 'button[action=save]' означает: "найти РІСЃРµ РєРЅРѕРїРєРё СЃ action: 'save' внутри данного представР"ения Рё подписаться РЅР° РёС… событие click". Рто РїРѕР·РІРѕР"яет избежать жёстких СЃСЃС‹Р"РѕРє Рё обеспечивает гибкость РїСЂРё рефакторинге.
Р’ MVVM СЂРѕР"СЊ посредника между представР"ением Рё РјРѕРґРµР"СЊСЋ играет ViewModel (Ext.app.ViewModel). Рто автономный объект, содержащий Р"РѕРєР°Р"СЊРЅРѕРµ состояние представР"ения, вычисР"яемые РїРѕР"СЏ Рё РїСЂРёРІСЏР·РєРё (bindings). ViewModel РЅРµ знает Рѕ контроР"Р"ере Рё РЅРµ связан СЃ жизненным цикР"РѕРј представР"ения напрямую — РѕРЅ существует параР"Р"РµР"СЊРЅРѕ Рё уничтожается вместе СЃ представР"ением. Его РіР"авная функция — обеспечить реактивность без императивного РєРѕРґР°.
РљР"ючевой механизм MVVM — двусторонняя РїСЂРёРІСЏР·РєР° данных (two-way binding). РљРѕРіРґР° разработчик РѕР±СЉСЏРІР"яет РїСЂРёРІСЏР·РєСѓ между РїРѕР"ем firstName РІ ViewModel Рё значением textfield, то Р"СЋР±РѕРµ изменение РІ текстовом РїРѕР"Рµ автоматически РѕР±РЅРѕРІР"яет firstName, Р° Р"СЋР±РѕРµ программное изменение firstName — РѕР±РЅРѕРІР"яет текстовое РїРѕР"Рµ. Р”Р"СЏ СЃР"ожных СЃР"учаев поддерживаются формуР"С‹ — функции, зависящие РѕС‚ РґСЂСѓРіРёС… РїРѕР"ей Рё автоматически пересчитываемые РїСЂРё РёС… изменении (например, fullName = firstName + ' ' + lastName). Важно: формуР"С‹ РЅРµ СЏРІР"яются выражениями РІ РєРѕРґРµ — РѕРЅРё декР"аративно описываются РІ конфигурации ViewModel Рё управР"яются фреймворком, что РёСЃРєР"ючает побочные эффекты Рё цикР"ические зависимости.
Р MVC, Рё MVVM РјРѕРіСѓС‚ сосуществовать РІ РѕРґРЅРѕРј РїСЂРёР"ожении — крупные раздеР"С‹ строятся РїРѕ MVVM (например, форма редактирования), Р° РіР"РѕР±Р°Р"ьная навигация, аутентификация, интеграция СЃ внешними API — управР"яются контроР"Р"ерами. Рто РїРѕР·РІРѕР"яет выбирать оптимаР"СЊРЅСѓСЋ РјРѕРґРµР"СЊ РІ зависимости РѕС‚ задачи.
Работа с данными
Р’ Ext JS данные отдеР"ены РѕС‚ интерфейса РЅР° архитектурном СѓСЂРѕРІРЅРµ. Даже простая табР"ица РЅРµ содержит данных "РІ себе" — РѕРЅР° Р"ишь отображает содержимое храниР"ища (Ext.Data.Store), которое, РІ СЃРІРѕСЋ очередь, управР"яет РєРѕР"Р"екцией экземпР"СЏСЂРѕРІ РјРѕРґРµР"Рё (Ext.Data.Model).
РњРѕРґРµР"СЊ — это РЅРµ просто POJO-объект. Рто РїРѕР"ноценный РєР"асс СЃ строгим описанием структуры — каждое РїРѕР"Рµ декР"арируется СЃ типом (string, int, date, boolean, auto), РїСЂРё необходимости — СЃ РІР°Р"идатором (presence, length, format, кастомная функция), конвертером (convert) Рё СѓРјРѕР"чатеР"ьным значением (defaultValue). РњРѕРґРµР"СЊ поддерживает ассоциации — hasMany, belongsTo, hasOne, что РїРѕР·РІРѕР"яет строить графы данных без ручного сшивания объектов.
ХраниР"ище выступает РІ СЂРѕР"Рё буфера данных Рё координатора операций. РћРЅРѕ отвечает Р·Р°:
— загрузку записей из источника (через прокси),
— Р"РѕРєР°Р"СЊРЅРѕРµ кэширование Рё сортировку,
— отсР"еживание изменений ("грязных" записей),
— пакетную синхронизацию с сервером (sync()),
— пагинацию Рё фиР"ьтрацию РЅР° РєР"иенте РёР"Рё сервере.
РљР"ючевая особенность: храниР"ище РЅРµ просто "хранит" данные — РѕРЅРѕ управР"яет РёС… состоянием. Запись может находиться РІ РѕРґРЅРѕРј РёР· режимов — NEW, EDIT, COMMIT, REJECT. РџСЂРё вызове record.set('field', value) храниР"ище автоматически помечает запись как изменённую Рё добавР"яет её РІ очередь РЅР° синхронизацию. Рто РїРѕР·РІРѕР"яет реаР"изовать СЃР"ожные сценарии — например, отмену всех изменений (rejectChanges()) РёР"Рё выборочную отправку (getModifiedRecords()).
Загрузка Рё сохранение данных осуществР"яются через РїСЂРѕРєСЃРё (Ext.Data.proxy.Proxy). РџСЂРѕРєСЃРё абстрагируют СЃРїРѕСЃРѕР± взаимодействия СЃ источником:
— Ajax — HTTP-запросы (GET/POST/PUT/DELETE),
— Rest — строгая REST-семантика,
— Memory — данные тоР"СЊРєРѕ РІ памяти (РґР"СЏ тестов РёР"Рё временных РєРѕР"Р"екций),
— LocalStorage Рё SessionStorage — постоянство РЅР° РєР"иенте,
— Direct — интеграция СЃ серверными RPC-методами (например, через Ext.Direct РІ СЃРІСЏР·РєРµ СЃ Java РёР"Рё .NET).
Каждый РїСЂРѕРєСЃРё может РІРєР"ючать ридер (reader) Рё писатеР"СЊ (writer) — РєР"ассы, отвечающие Р·Р° десериаР"изацию ответа сервера Рё сериаР"изацию запроса. Поддерживаются JSON, XML, массивы. РџСЂРё необходимости РјРѕР¶РЅРѕ реаР"изовать кастомный ридер РґР"СЏ нестандартных форматов (например, РґР"СЏ ответов старых SOAP-сервисов).
Важно: РІСЃРµ операции СЃ данными асинхронны РїРѕ СѓРјРѕР"чанию, РЅРѕ фреймворк обеспечивает СЃРѕРіР"асованность состояния даже РїСЂРё параР"Р"РµР"ьных запросах. Например, есР"Рё РїСЂРѕРёСЃС…РѕРґРёС‚ редактирование записи РІРѕ время загрузки РЅРѕРІРѕР№ страницы, храниР"ище РЅРµ потеряет изменения — РѕРЅРё сохраняются РІ буфере РґРѕ завершения операции.
Рнструменты разработки
Р”Р"СЏ поддержки жизненного цикР"Р° проекта Sencha предоставиР"Р° РґРІР° РєР"ючевых инструмента: Sencha Cmd Рё Sencha Architect.
Sencha Cmd — это РєРѕРЅСЃРѕР"ьная утиР"ита, сочетающая функции сборщика, менеджера зависимостей, генератора РєРѕРґР° Рё сервера разработки. РћРЅР° РёСЃРїРѕР"ьзует Apache Ant РїРѕРґ капотом, РЅРѕ скрывает СЃР"ожность через высокоуровневые команды:
— sencha app init — инициаР"изация структуры проекта,
— sencha app build — СЃР±РѕСЂРєР° production-версии СЃ минификацией, объединением файР"РѕРІ, tree-shaking (РІ РїРѕР·РґРЅРёС… версиях), внедрением темы,
— sencha app watch — режим разработки СЃ С…РѕС‚-СЂРµР"оадом Рё инкрементаР"СЊРЅРѕР№ пересборкой,
— sencha generate model/view/controller — шабР"РѕРЅРЅРѕРµ создание РєР"ассов СЃ СЃРѕР±Р"юдением СЃРѕРіР"ашений РѕР± именовании.
РћСЃРѕР±РѕРµ внимание СѓРґРµР"ено темизации. Тема РІ Ext JS — это проект РЅР° Sass СЃ параметризацией — цвета, отступы, радиусы СЃРєСЂСѓРіР"ений, шрифты вынесены РІ переменные. Sencha Cmd РєРѕРјРїРёР"ирует Sass РІ CSS СЃ учётом иерархии насР"едования тем Рё оптимизацией РґР"СЏ конкретного набора РёСЃРїРѕР"ьзуемых компонентов (так называемая theme slice), что РїРѕР·РІРѕР"яет сократить размер резуР"ьтирующего CSS РЅР° 60–80 % РїРѕ сравнению СЃ РїРѕР"РЅРѕР№ СЃР±РѕСЂРєРѕР№.
Sencha Architect — РІРёР·СѓР°Р"ьный IDE-инструмент (РЅР° базе Electron), РїРѕР·РІРѕР"яющий проектировать интерфейс перетаскиванием компонентов, настраивать РёС… свойства РІ панеР"Рё инспектора, привязывать данные, описывать события — РІСЃС‘ это СЃ генерацией РІР°Р"РёРґРЅРѕРіРѕ Ext JS-РєРѕРґР°. Architect РЅРµ заменяет ручное кодирование, РЅРѕ значитеР"СЊРЅРѕ ускоряет создание макетов, форм Рё прототипов, особенно РїСЂРё работе СЃ непрограммистами (анаР"итиками, дизайнерами). РљРѕРґ, сгенерированный Architect, РїРѕР"ностью совместим СЃ ручной разработкой Рё может быть доработан РІ Р"СЋР±РѕРј редакторе.
РћР±Р° инструмента интегрируются СЃ системами контроР"СЏ версий: проект Sencha — это обычная файР"овая структура без бинарных артефактов (Р·Р° РёСЃРєР"ючением app.json, который текстовый), что РїРѕР·РІРѕР"яет РёСЃРїРѕР"ьзовать Git, SVN Рё С‚.Рї. без ограничений.
Установка Рё Р"ицензирование
Ext JS исторически состояР" РёР· РґРІСѓС… частей: Ext Core Рё Ext JS (базовая Р±РёР±Р"иотека + компоненты).
Ext Core — это Р"егковесный СЏРґСЂРѕ (РѕРєРѕР"Рѕ 30 РљР‘ минифицированного РєРѕРґР°), предоставР"яющее кроссбраузерные абстракции РґР"СЏ работы СЃ DOM, событиями, Ajax, утиР"итами (Ext.each, Ext.merge, Ext.isString Рё С‚.Рґ.). РћРЅ распространяР"СЃСЏ РїРѕ Р"ицензии MIT Рё РјРѕРі СЃРІРѕР±РѕРґРЅРѕ РёСЃРїРѕР"ьзоваться даже РІ коммерческих проектах без упоминания Sencha. Однако СЃ выходом Ext JS 4 (2011) Ext Core Р±С‹Р" РїРѕР"ностью интегрирован РІ РѕСЃРЅРѕРІРЅСѓСЋ Р±РёР±Р"иотеку, Рё отдеР"СЊРЅРѕРіРѕ СЂРµР"РёР·Р° Р±РѕР"ьше РЅРµ выпускаР"РѕСЃСЊ.
Сам Ext JS СЃ версии 2.0 (2008) перешёР" РЅР° РґРІРѕР№РЅСѓСЋ Р"ицензию:
— GNU General Public License, версия 3 (GPL v3) — РґР"СЏ open-source проектов, распространяемых также РїРѕРґ GPL v3. Рто означает, что РїСЂРёР"ожение, РёСЃРїРѕР"ьзующее Ext JS РїРѕ GPL, РґРѕР"Р¶РЅРѕ быть открытым, Рё его исходный РєРѕРґ — доступен РїРѕР"ьзоватеР"СЏРј.
— Коммерческая Р"ицензия — РґР"СЏ закрытых, проприетарных РїСЂРёР"ожений. Лицензия привязана Рє разработчику РёР"Рё организации, РІРєР"ючает право РЅР° техническую поддержку, РѕР±РЅРѕРІР"ения Рё РёСЃРїРѕР"ьзование РІ SaaS-продуктах без раскрытия РёСЃС…РѕРґРЅРѕРіРѕ РєРѕРґР°.
Такой РїРѕРґС…РѕРґ типичен РґР"СЏ РјРЅРѕРіРёС… enterprise-Р±РёР±Р"иотек (например, Qt, iText). РћРЅ РїРѕР·РІРѕР"яет беспР"атно РёСЃРїРѕР"ьзовать фреймворк РІ некоммерческой РёР"Рё open-source разработке, РЅРѕ требует РѕРїР"аты РїСЂРё коммерческом внедрении. Важно — просто РёСЃРїРѕР"ьзование Ext JS РІ веб-РїСЂРёР"ожении, даже есР"Рё РѕРЅРѕ доступно РІ интернете, СѓР¶Рµ считается распространением — Рё есР"Рё РєРѕРґ закрыт, требуется коммерческая Р"ицензия.
РЎ 2021 РіРѕРґР°, РїРѕСЃР"Рµ перехода РїРѕРґ управР"ение Idera, РїРѕР"итика ужесточиР"ась: беспР"атная GPL-версия Р±РѕР"ьше РЅРµ РїСѓР±Р"икуется РЅР° общедоступных CDN (РІСЂРѕРґРµ npm без авторизации), Р° доступ Рє репозиторию npm требует регистрации Рё принятия Р"ицензионного СЃРѕРіР"ашения. Рто РЅРµ отменяет право РёСЃРїРѕР"ьзовать СѓР¶Рµ загруженные GPL-версии, РЅРѕ затрудняет старт новых open-source проектов.
Установка сегодня осуществР"яется преимущественно через npm, РЅРѕ СЃ обязатеР"СЊРЅРѕР№ аутентификацией РІ приватном репозитории Sencha (даже РґР"СЏ GPL-СЃР±РѕСЂРѕРє):
npm login --registry=https://npm.sencha.com --scope=@sencha
npm install @sencha/ext-web-components
РђР"ьтернативно — загрузка архива СЃ сайта Рё ручная инициаР"изация проекта через sencha app init --ext <путь>.
Пример — декР"аративное описание компонента Рё работа СЃ данными
Рассмотрим типичный сценарий — редактируемая форма СЃ РїСЂРёРІСЏР·РєРѕР№ Рє РјРѕРґРµР"Рё Рё сохранением РЅР° сервер.
СначаР"Р° опредеР"яется РјРѕРґРµР"СЊ:
Код ITЗагрузка примера кода…
Затем — представР"ение СЃ ViewModel:
Код ITЗагрузка примера кода…
ViewModel обеспечивает реактивность:
Код ITЗагрузка примера кода…
КонтроР"Р"ер связывает РІСЃС‘ вместе:
Код ITЗагрузка примера кода…
Обратите внимание:
— Нет ручной работы с DOM (document.getElementById),
— Нет императивного копирования значений (textField.getValue()),
— Р’Р°Р"идация РґРµР"егирована РјРѕРґРµР"Рё,
— Сохранение — через save() РјРѕРґРµР"Рё, который РёСЃРїРѕР"ьзует РїСЂРѕРєСЃРё,
— Рнтерфейс реагирует РЅР° изменения автоматически Р±Р"агодаря bind.
Рто Рё есть суть РїРѕРґС…РѕРґР° Ext JS: описание вместо императивного управР"ения.
Современный статус Рё Р°Р"ьтернативы
РќР° 2025 РіРѕРґ Ext JS остаётся активно поддерживаемым продуктом, РЅРѕ его СЂРѕР"СЊ РІ новых проектах измениР"ась. РћРЅ редко выбирается РґР"СЏ стартапов РёР"Рё consumer-РїСЂРёР"ожений, РіРґРµ важна скорость итераций Рё экосистема open-source. Однако РІ корпоративном секторе — особенно РІ финансах, государственном управР"ении, промышР"енной автоматизации — РѕРЅ РїРѕ-прежнему востребован там, РіРґРµ:
— требуется поддержка legacy-браузеров (IE11 в госсекторе),
— РЅСѓР¶РЅС‹ готовые enterprise-компоненты "РёР· РєРѕСЂРѕР±РєРё" (сетки СЃ экспортами, РїР"анировщики, карты, отчёты),
— критична предсказуемость Рё сопровождаемость РІ течение 10+ Р"ет,
— интеграция СЃ Java/.NET-бэкендами через Ext.Direct РёР"Рё SOAP.
Sencha РїСЂРѕРґРѕР"жает выпускать РѕР±РЅРѕРІР"ения (РїРѕСЃР"едняя LTS-версия — Ext JS 7.6, 2023 Рі.), добавР"СЏСЏ поддержку TypeScript, СѓР"учшая производитеР"ьность рендеринга, интегрируя Web Components. Проект ExtWebComponents РїРѕР·РІРѕР"яет РёСЃРїРѕР"ьзовать отдеР"ьные компоненты Ext JS (например, ext-grid, ext-chart) РІ Р"СЋР±РѕРј современном фреймворке как стандартные HTML-теги — это гибридный путь миграции.
РђР"ьтернативы СѓСЃР"РѕРІРЅРѕ РґРµР"ятся РЅР°:
— БибР"иотеки компонентов:
-
AG Grid;
-
Kendo UI;
-
Syncfusion — предР"агают СЃС…РѕР¶РёРµ РїРѕ функционаР"ьности сетки Рё контроР"С‹;
-
РЅРѕ без единой архитектуры РїСЂРёР"ожения. — Фреймворки СЃ enterprise-Р±РёР±Р"иотеками:
-
Angular + DevExtreme;
-
React + Material-UI + кастомная Р"РѕРіРёРєР° — гибче;
-
РЅРѕ требуют Р±РѕР"ьше СѓСЃРёР"РёР№ РЅР° интеграцию;
-
тестирование. — Low-code РїР"атформы — ELMA365, Creatio, OutSystems — СѓС…РѕРґСЏС‚ РѕС‚ ручного кодирования вообще, РЅРѕ жертвуют гибкостью.
Выбор Ext JS сегодня — это расчёт РЅР° РґРѕР"госрочную стабиР"ьность, РјРёРЅРёРјР°Р"СЊРЅРѕРµ время вывода MVP Рё соответствие регуР"яторным требованиям. Р’ этом смысР"Рµ РѕРЅ остаётся СѓРЅРёРєР°Р"ьным решением РІ своём РєР"ассе.
РћС‚Р"адка Ext JS РІ инструментах разработчика
РћРґРЅРѕ РёР· СЃРёР"ьных преимуществ Ext JS — высокая интроспектируемость РїСЂРёР"ожения РІРѕ время выпоР"нения. Фреймворк РЅРµ скрывает внутреннее состояние — РІСЃРµ объекты доступны РёР· РєРѕРЅСЃРѕР"Рё браузера, имеют читаемые имена РєР"ассов, иерархию РІР"адения, СЃСЃС‹Р"РєРё РЅР° конфигурации Рё данные. Рто создаёт мощную РѕСЃРЅРѕРІСѓ РґР"СЏ диагностического анаР"РёР·Р° без необходимости РІ специаР"изированных РїР"агинах (РІ РѕС‚Р"ичие, например, РѕС‚ React DevTools, РіРґРµ требуется отдеР"СЊРЅРѕРµ расширение).
РљР"ючевой инструмент — РіР"РѕР±Р°Р"ьный объект Ext, предоставР"яющий доступ Рє реестру компонентов, РєР"ассов, РІРёРґРјРѕРґРµР"ей Рё утиР"итам. Начать РѕС‚Р"адку РјРѕР¶РЅРѕ СЃ запроса Рє Ext.ComponentQuery, анаР"огичного CSS-СЃРµР"екторам, РЅРѕ работающему РЅР° СѓСЂРѕРІРЅРµ объектной РјРѕРґРµР"Рё:
// Найти все панели на странице
Ext.ComponentQuery.query('panel');
// Найти компонент по itemId (локальному, уникальным в пределах контейнера)
Ext.ComponentQuery.query('#myButton');
// Найти активное окно верхнего уровня
Ext.ComponentQuery.query('window[active=true]')[0];
// Найти грид с указанным xtype и получить его хранилище
var grid = Ext.ComponentQuery.query('myapp-grid')[0];
var store = grid.getStore();
store.getData().items; // массив записей
Каждый компонент, храниР"ище, РјРѕРґРµР"СЊ имеет метод .toJSON() РёР"Рё .get(), возвращающий РїР"РѕСЃРєСѓСЋ структуру текущего состояния — это особенно РїРѕР"езно РїСЂРё проверке значений РїРѕР"ей РёР"Рё изменений РІ записи:
// Получить текущее значение из текстового поля
var field = Ext.ComponentQuery.query('#emailField')[0];
field.getValue(); // строка
// Рли через модель, привязанную Рє ViewModel
var vm = field.up('form').getViewModel();
vm.get('record.email'); // то же значение, но из модели
// Посмотреть все "грязные" поля записи
var record = vm.get('record');
record.getChanges(); // { firstName: 'РќРѕРІРѕРµ', email: 'new@ex.ample' }
Жизненное дерево РїСЂРёР"ожения РјРѕР¶РЅРѕ РІРёР·СѓР°Р"изировать через РІР"адеР"ьческие СЃСЃС‹Р"РєРё. РЈ Р"СЋР±РѕРіРѕ компонента есть свойства:
ownerCt— непосредственный родитеР"СЊСЃРєРёР№ контейнер,up()— метод РґР"СЏ подъёма РїРѕ иерархии (component.up('form')найдёт Р±Р"ижайшую форму выше),down()— СЃРїСѓСЃРє РІРЅРёР· РїРѕ дереву (form.down('#submitBtn')),floatingItems,menu,toolbars— СЃСЃС‹Р"РєРё РЅР° вспомогатеР"ьные СЌР"ементы.
При возникновении ошибки в обработчике события (например, TypeError: Cannot read property 'save' of undefined) достаточно:
- Поставить breakpoint в обработчике (через
debugger;РёР"Рё РІ Sources), - Р’ РєРѕРЅСЃРѕР"Рё вызвать
this— РѕРЅ укажет РЅР° экземпР"СЏСЂ контроР"Р"ера РёР"Рё компонента, откуда вызван метод, - РСЃРїРѕР"ьзовать
argumentsРёР"Рё замыкание, чтобы уточнить контекст вызова.
Важно: РІ production-сборках Ext JS РїРѕ СѓРјРѕР"чанию РІРєР"ючается minification, что "СЃС…Р"опывает" имена методов Рё свойств. Р”Р"СЏ РѕС‚Р"адки рекомендуется РёСЃРїРѕР"ьзовать Разработка-СЃР±РѕСЂРєСѓ (ext-all-debug.js РёР"Рё СЃР±РѕСЂРєР° через sencha app build Разработка), РіРґРµ сохраниР"РёСЃСЊ имена РєР"ассов, параметров Рё комментарии.
Р”Р"СЏ диагностики РїСЂРѕР±Р"ем СЃ загрузкой данных РїРѕР"езно СЃР"едить Р·Р° сетевыми запросами (РІРєР"адка Сеть), РЅРѕ РЅРµ тоР"СЊРєРѕ Р·Р° HTTP-статусом — Ext JS добавР"яет Рє ответу сервера загоР"РѕРІРѕРє X-Sencha-Trace, Р° РІ РєРѕРЅСЃРѕР"Рё РјРѕР¶РЅРѕ РІРєР"ючить Р"огирование РїСЂРѕРєСЃРё:
Ext.Data.Connection.prototype.log = true;
// или на уровне прокси модели
proxy: {
type: 'ajax',
url: '/api/data',
listeners: {
exception: function(proxy, response) {
console.error('Ошибка загрузки:', response.responseText);
}
}
}
Таким образом, РѕС‚Р"адка РІ Ext JS — это цеР"енаправР"енный осмотр состояния через открытую, документированную объектную РјРѕРґРµР"СЊ. Рто снижает РїРѕСЂРѕРі РІС…РѕРґР° РґР"СЏ новых разработчиков РІ СѓР¶Рµ существующий проект Рё повышает предсказуемость поведения системы.
РњРёРєСЃРёРЅС‹
Р’ РѕС‚Р"ичие РѕС‚ РєР"ассического насР"едования ("is-a"), РіРґРµ РєР"асс расширяет РґСЂСѓРіРѕР№ РєР"асс, Ext JS активно РёСЃРїРѕР"ьзует РјРёРєСЃРёРЅС‹ (mixins) — механизм горизонтаР"СЊРЅРѕРіРѕ внедрения функционаР"ьности ("has-a"). РњРёРєСЃРёРЅ — это автономный РєР"асс, содержащий методы, свойства Рё обработчики событий, которые РјРѕРіСѓС‚ быть добавР"ены РІ Р"СЋР±РѕР№ РґСЂСѓРіРѕР№ РєР"асс без изменения его иерархии.
Синтаксис РѕР±СЉСЏРІР"ения РјРёРєСЃРёРЅР°:
Код ITЗагрузка примера кода…
РџРѕРґРєР"ючение Рє компоненту:
Ext.define('App.view.FormPanel', {
extend: 'Ext.form.Panel',
mixins: ['App.mixin.DirtyTracking'],
initComponent: function() {
this.callParent();
// Подписка на события полей — внутри миксина или здесь
this.on('fieldchange', this.onFieldChange, this);
}
});
Преимущества миксинов:
- Повторное РёСЃРїРѕР"ьзование — РѕРґРёРЅ Рё тот Р¶Рµ РјРёРєСЃРёРЅ РјРѕР¶РЅРѕ РїРѕРґРєР"ючить Рє форме, сетке, РґРёР°Р"РѕРіРѕРІРѕРјСѓ РѕРєРЅСѓ — Р"СЋР±РѕРјСѓ компоненту, нуждающемуся РІ трекинге изменений.
- РаздеР"ение ответственности — Р"РѕРіРёРєР° РІР°Р"идации, Р"огирования, доступности, Р"РѕРєР°Р"изации выносится РІ отдеР"ьные РјРёРєСЃРёРЅС‹, Р° РЅРµ размазывается РїРѕ базовым РєР"ассам.
- Рзбежание СЂРѕРјР±РѕРІРёРґРЅРѕРіРѕ насР"едования — РєРѕРіРґР° РґРІР° базовых РєР"асса предоставР"СЏСЋС‚ РѕРґРЅСѓ Рё ту Р¶Рµ функционаР"ьность (например,
DraggableРёResizable), РјРёРєСЃРёРЅС‹ РїРѕР·РІРѕР"СЏСЋС‚ комбинировать РёС… без РєРѕРЅС„Р"иктов.
Ext JS поставР"яется СЃ СЂСЏРґРѕРј встроенных РјРёРєСЃРёРЅРѕРІ:
Ext.util.Observable— добавР"яет систему событий (СѓР¶Рµ РІРєР"ючён РІExt.Base, так что СЏРІРЅРѕ РЅРµ требуется),Ext.mixin.Bindable— поддержка РїСЂРёРІСЏР·РѕРє (bindings),Ext.mixin.Selectable— поведение выбора (РґР"СЏ РіСЂРёРґРѕРІ, деревьев),Ext.mixin.Factoryable— фабричный паттерн РґР"СЏ динамического создания компонентов.
РњРёРєСЃРёРЅС‹ уважают жизненный цикР" компонента: есР"Рё РјРёРєСЃРёРЅ содержит метод initComponent, РѕРЅ будет вызван РїРѕСЃР"Рµ initComponent РѕСЃРЅРѕРІРЅРѕРіРѕ РєР"асса, РЅРѕ РґРѕ afterRender. Рто РїРѕР·РІРѕР"яет безопасно инициаР"изировать состояние, РЅРµ нарушая РїРѕСЂСЏРґРєР° событий.
Микшины — РЅРµ "патчинг" прототипа. РћРЅРё внедряются РЅР° этапе опредеР"ения РєР"асса, Рё каждый экземпР"СЏСЂ РїРѕР"учает СЃРІРѕСЋ РєРѕРїРёСЋ методов (РІ предеР"ах ограничений JavaScript), что РёСЃРєР"ючает побочные эффекты РїСЂРё совместном РёСЃРїРѕР"ьзовании.
Ext JS РІ контексте low-code РїР"атформ
РџР"атформы РєР"асса Creatio (ранее bpm’online), ELMA365 Рё анаР"огичные enterprise-решения РґР"СЏ автоматизации бизнес-процессов часто РёСЃРїРѕР"СЊР·СѓСЋС‚ Ext JS как базовую front-end-РїР"атформу РґР"СЏ построения РїРѕР"ьзоватеР"СЊСЃРєРёС… интерфейсов — особенно РІ РјРѕРґСѓР"СЏС…, требующих высокой интерактивности — CRM-панеР"Рё, конструкторы форм, анаР"итические дашборды, редакторы процессов.
Важно подчеркнуть: РІ таких системах Ext JS РЅРµ РёСЃРїРѕР"ьзуется "РІ чистом РІРёРґРµ". РћРЅ интегрируется РІ собственную метасистему:
- Вместо ручного РѕР±СЉСЏРІР"ения
Ext.define('MyApp.view...')интерфейсы описываются РІ метаданных (XML РёР"Рё JSON-конфигурации), которые РІ runtime РєРѕРјРїРёР"ируются РІРѕ внутренние объекты Ext JS. - РљР"ассы компонентов заменяются РјРѕРґСѓР"СЏРјРё страниц (например,
BasePageV2,SectionPageV2РІ Creatio), которые насР"едуют РѕС‚ абстракций РїР"атформы, Р° РЅРµ напрямую РѕС‚Ext.panel.Panel. - РџСЂРёРІСЏР·РєР° данных идёт РЅРµ Рє
Ext.Data.Model, Р° Рє сущностям доменной РјРѕРґРµР"Рё (например,Contact,Account), управР"яемым серверным API Рё РєР"иентским кэшем. - Механизм событий расширяется РїР"атформо-зависимыми триггерами ("РґРѕ сохранения", "РїРѕСЃР"Рµ загрузки", "РїСЂРё смене статуса"), которые трансР"ируются РІ вызовы Ext-событий.
Тем РЅРµ менее, знание Ext JS даёт разработчику критическое преимущество РїСЂРё кастомизации таких РїР"атформ:
- Понимание иерархии компонентов РїРѕР·РІРѕР"яет точно находить цеР"евые СЌР"ементы через
ComponentQuery. - Опыт работы с
ViewModelРёbindingsускоряет создание реактивных РїРѕР"ей Рё вычисР"яемых значений. - Знание жизненного цикР"Р° (
init,render,destroy) помогает корректно внедрять Р"РѕРіРёРєСѓ без утечек памяти. - Умение РѕС‚Р"аживать через РєРѕРЅСЃРѕР"СЊ РїРѕР·РІРѕР"яет быстро Р"РѕРєР°Р"изовать РїСЂРѕР±Р"ему РІ кастомном РєРѕРґРµ, РЅРµ дожидаясь РїРѕР"РЅРѕР№ пересборки метапакета.
Например, РІ Creatio страница контакта — это экземпР"СЏСЂ РєР"асса, унасР"едованного РѕС‚ BasePageV2, который внутри содержит Ext.container.Container СЃ РІРєР"адками, формами, гридами. РџСЂРё переопредеР"ении метода init разработчик может добавить РєРЅРѕРїРєСѓ:
init: function() {
this.callParent(arguments);
this.addButton({
caption: "Проверить контрагента",
tag: "checkContragent",
click: { bindTo: "onCheckContragentClick" }
});
}
Здесь addButton — метод РїР"атформы, РЅРѕ РѕРЅ создаёт стандартный Ext.button.Button, подписанный РЅР° событие через механизм, совместимый СЃ handler РІ Ext JS.
Таким образом, Ext JS здесь выступает как РґРІРёР¶РѕРє отрисовки Рё поведения, Р° РїР"атформа — как надстройка метамодеР"Рё, безопасности, интеграций Рё управР"ения жизненным цикР"РѕРј. Знание СЏРґСЂР° РїРѕР·РІРѕР"яет эффективно работать СЃ надстройкой, РёСЃРїРѕР"СЊР·СѓСЏ Р·Р°Р"оженные расширения.
Базовый разбор HTTP Рё HTTPS находится РІ отдеР"СЊРЅРѕР№ статье — HTTP как РѕСЃРЅРѕРІР° веб-интеграций.