Pull to refresh

В ожидании ExtJS 4: Динамическая загрузка и новая система классов

Reading time11 min
Views6.1K
Original author: Ed Spencer
От переводчика: Sencha Inc, производитель известного RIA-фреймворка Ext JS, заговорила о грядущей четвертой версии 22 ноября прошлого года. Релиз обещанного планировался на 28 февраля.

Что бы подогреть интерес комьюнити (ведь API, по словам разработчиков, изменилось значительно), была обещана публичная альфа- или бета-версия «в течении пары недель». Прошло два месяца, но обещанного пока нет.

Понимая, что была совершена маркетинговая ошибка – слишком рано заявили о новом продукте и сорвали сроки его презентации – разработчики решили немного схитрить, выкладывая обещанную «бету» по частям: пакет за пакетом.

Вашему вниманию предлагается перевод первой статьи из официального блога фреймворка, посвященной попытке эмуляции «взрослого» ООП средствами JavaScript в реализации Ext JS 4.

Статья, в первую очередь, будет интересна тем, кто уже пользовался предыдущими версиями фреймворка – автор рассчитывает на то, что читатель уже знаком с архитектурой Ext JS.

Встречаем Ext JS 4


Сегодня мы с волнением представляем Вашему вниманию «первенца» в череде абсолютно новых возможностей Ext JS 4. В течении нескольких недель мы будем выкладывать нашу бета-версию Ext JS – пакет за пакетом. Несмотря на то, что изначально мы планировали выпуск полной «беты» где-то в это время, некоторые части фреймворка стабилизируются медленнее, чем этого бы хотелось, потому мы решили публиковать пакеты по очереди. Сегодня мы начнем с абсолютно новой системы классов в Ext JS 4.

Язык JavaScript изначально не предусматривал понятия «класс», что могло быть непривычным для новичков. Ext JS всегда комплектовался собственной системой классов, основанной на мощнейшем инструменте прототипирования. Такое решение позволяет программистам использовать более традиционный объектно-ориентированный подход в разработке.

С выходом Ext JS 4, мы переводим систему классов на новый уровень, добавляя в нее новые возможности, которые должны облегчить Вашу разработку и придать ей еще больше гибкости. Ext 4 представит четыре нововведения – объявления классов (class definitions), примеси (mixins), геттеры (getters) и сеттеры (setters) для конфигураций, а так же загрузку зависимостей (dependency loading).



На иллюстрации выше отмечены несколько преимуществ новой системы классов, например Draggable и Resizable стали примесями.

Объявление класса


Для сравнения давайте посмотрим, как мы создавали новый класс в Ext JS 3. В этом примере мы создаем фиктивное окно авторизации, которое расширяет стандартный класс Ext.Window:

  1.  
  2. //Ext JS 3.x class definition
  3. MyApp.LoginWindow = Ext.extend(Ext.Window, {
  4.     title: 'Log in',
  5.  
  6.     initComponent: function() {
  7.         Ext.apply(this, {
  8.             items: [
  9.                 {
  10.                     xtype: 'textfield',
  11.                     name : 'username',
  12.                     fieldLabel: 'Username'
  13.                 },
  14.                 ...
  15.             ]
  16.         });
  17.  
  18.         MyApp.LoginWindow.superclass.initComponent.apply(this, arguments);
  19.     }
  20. });
  21.  


Такой подход, весьма вероятно, знаком большинству из вас и он хорошо справляется со своей задачей, хотя и не лишен недостатков. Например, если Ext.Window не объявлен до момента создания нашего класса, то выполнение этого кода вызовет ошибку и наше приложение может аварийно прекратить работу. Аналогично, если пространство имен MyApp не было объявлено раннее, мы тоже получим ошибку. Обе этих проблемы решаются, если классы будут создаваться по новой идеологии:

  1.  
  2. //Ext JS 4.x class definition
  3. Ext.define('MyApp.LoginWindow', {
  4.     extend: 'Ext.Window',
  5.  
  6.     title: 'Log in',
  7.  
  8.     initComponent: function() {
  9.         Ext.apply(this, {
  10.             items: [
  11.                 //as above
  12.             ]
  13.         });
  14.  
  15.         MyApp.LoginWindow.superclass.initComponent.apply(this, arguments);
  16.     }
  17. });
  18.  


В Ext JS 4 на классы можно ссылаться по строковому представлению их имен – значит, мы никогда не получим ошибок, описанных выше. Менеджер классов достаточно умен, что бы проверить – объявлен ли уже Ext.Window. Если нет – то отложить создание MyApp.LoginWindow до тех пор, пока нужный класс не будет доступен. Мы больше не обязаны следовать четкому порядку загрузки в наших приложениях, разрешая фреймоворку заботится обо всем.

Примеси


Первой из новых возможностей системы являются примеси. Примесь — это именованная объявленная связка поведенческой логики и параметров конфигурации, которые могут быть «подмешены» к классу, тем самым расширяя его возможности. Что бы воспользоваться преимуществами примесей, просто примените их к объявлению Вашего класса.

Например, что бы объект вашего класса можно было перемещать по экрану, достаточно применить к классу примесь Draggable. «Подмешивать» к классу можно произвольное количество примесей – таким образом можно реализовать множественное наследование. Это именно то, чего на протяжении длительного времени было очень сложно добиться, используя большинство JavaScript-фреймворков.

Примеси задаются примерно так:

  1.  
  2. Ext.define('Sample.Musician', {
  3.     extend: 'Sample.Person',
  4.  
  5.     mixins: {
  6.         guitar: 'Sample.ability.CanPlayGuitar',
  7.         compose: 'Sample.ability.CanComposeSongs',
  8.         sing: 'Sample.ability.CanSing'
  9.     }
  10. });
  11.  


Позволю себе повториться, все имена классов ссылаются друг на друга по строковым наименованиям — у нас не возникнет ошибок в используемых примесях, если они еще не загружены. Класс может пользоваться возможностями любого количества примесей, а сами примеси задаются чрезвычайно просто:

  1.  
  2. Ext.define('Sample.ability.CanPlayGuitar', {
  3.     playGuitar: function() {
  4.         //code to play
  5.     }
  6. });
  7.  


Автоматические сеттеры и геттеры для конфигураций


Большинство классов в Ext JS настраивается путем передачи в конструктор конфигурационного объекта. Используя геттеры и сеттеры, конфигурационные объекты могут быть изменены, а правки — применены во время работы приложения. У Ext JS 4 существует политика соглашения об именовании опций конфигурации, которую следует учитывать при использовании этих функций. Такой подход позволяет сократить время разработки, консистентность API и серьезно уменьшить объем загружаемого файла. Давайте рассмотрим пример:

  1.  
  2. Ext.define('MyClass', {
  3.     config: {
  4.         title: 'Default Title'
  5.     }
  6. });
  7.  


В приведенням выше фрагменте мы объявляем класс с единственным настраиваемым свойством: title. Мы так же указываем значение по умолчанию для этого свойства, в данном случае это ‘Default title’. Благодаря новой системе объявления классов в Ext JS 4, фреймворк автоматически создаст геттеры и сеттеры для нашего класса. Если бы мы пользовались Ext JS 3.3, то пришлось бы писать шаблонный код:

  1.  
  2. MyClass = Ext.extend(MyBaseClass, {
  3.     title: 'Default Title',
  4.  
  5.     getTitle: function() {
  6.         return this.title;
  7.     },
  8.  
  9.     resetTitle: function() {
  10.         this.setTitle('Default Title');
  11.     },
  12.  
  13.     setTitle: function(newTitle) {
  14.        this.title = this.applyTitle(newTitle) || newTitle;
  15.     },
  16.  
  17.     applyTitle: function(newTitle) {
  18.          //custom code here
  19.     }
  20. });
  21.  


Теперь же библиотека создаст за нас все четыре функции. В большинстве случаев, простого обновления значения переменных вполне достаточно, но бывают случаи, когда следует предпринять какие-то действия в момент изменения конфигурации. К примеру, если наш класс отображает заголовок в некотором DOM-элементе, у нас есть возможность обновить этот элемент, используя вот такую конструкцию:

  1.  
  2. xt.define('MyClass', {
  3.    extend: 'MyBaseClass',
  4.  
  5.     config: {
  6.         title: 'Default Title'
  7.     },
  8.  
  9.     applyTitle: function(newTitle) {
  10.         Ext.get('titleEl').update(newTitle);
  11.     }
  12. });
  13.  


Все четыре функции создаются автоматически и мы можем переопределить любую из них точно так же легко, как это сделали выше с applyTitle. Соответственно, мы не только пишем меньше кода в наших классах, но и существенно урезаем размер как самого ExtJS, так и нашего приложения – облегчая таким образом загрузку файла конечным пользователем.

Динамическая Загрузка


Перед нами предстали всего несколько преимуществ новой системы классов , но впереди нас ждет гораздо больше интересного и к чему мы позже вернемся. Однако сейчас самое время представить на Ваш суд нечто абсолютно новое для Ext JS 4: динамическую загрузку.

До сих пор, пользуясь любой версией Ext JS, Вам приходилось загружать всю библиотеку для начала работы. Если Вам нужно было создать объект класса Ext.Window, класс нужно было выкачать заранее, иначе возникала ошибка. Все изменилось и упростилось с динамической загрузкой Ext JS 4:

  1.  
  2. Ext.require('Ext.Window', function() {
  3.     new Ext.Window({
  4.         title : 'Loaded Dynamically!',
  5.         width : 200,
  6.         height: 100
  7.     }).show();
  8. })
  9.  


Здесь мы просим Ext JS загрузить класс Ext.Window и вызвать функцию по готовности. Мы можем запросить любое количество классов путем передачи массива в Ext.require. Собственно, вот и все – просто до невозможности, основное волшебство скрыто от зрителя. Динамический загрузчик Ext JS 4 работает исключительно на стороне клиента и не требует никаких вмешательств в серверную часть. Более того, он автоматически разбирает зависимости, которые могут быть у загружаемого класса. В качестве примера, пусть Ext.Window выглядит вот так:

  1.  
  2. Ext.define('Ext.Window', {
  3.     extend: 'Ext.Panel',
  4.     requires: ['Ext.util.MixedCollection'],
  5.     mixins: {
  6.         draggable: 'Ext.util.Draggable'
  7.     }
  8. });
  9.  


Как только библиотека загрузила класс Ext.Window, она определяет зависимости, объявленные в секциях extend, require и в описаниях примесей.

Если какой-нибудь из необходимых классов еще не объявлен, то фреймоворк сначала подгрузит зависимость, а уже потом объявит Ext.Window. Благодаря соглашению именований, загрузчик автоматически знает, как определить нужный файл для каждого из классов. В данном случае, следующие файлы будут запрошены перед тем, как будет вызвана наша функция:
  • src/Window.js
  • src/Panel.js
  • src/util/MixedCollection.js
  • src/util/Draggable.js


Загрузчик работает рекурсивно – если у этих файлов есть неучтенные раннее зависимости, он будет запрашивать файлы до тех пор, пока все не будет готово к инициализации.

Несмотря на то, что в рабочем режиме рекомендуется не использовать режим «файл за файлом», такой подход позволяет обойтись без одного из самых давних и раздражающих моментов в использовании Ext JS – файла ext-all-debug.js.

До последнего времени мы рекомендовали использовать ext-all-debug.js во время разработки и ext-all.js в штатном режиме работы приложения. Отладочная версия содержит всю библиотеку целиком в читабельном виде, но и содержит около 60 000 строк кода. Соответственно, и так непростой процесс исправления ошибок усложняется еще больше: подсказка в стеке вызовов об исключении в 47657 строке ext-all-debug.js мало чем поможет. С другой стороны, использование динамического загрузчика позволит узнать, что проблема воникла в 56 строке файла src/data/JsonReader.js. И все это с полным стеком вызовов и корректными номерами строк для каждого файла.

На самом деле, это – серьезный шаг вперед в отладке Вашего приложения, да и с производительностью проблем не возникнет: при локальной разработке очень сложно заметить, что библиотека подгружается динамически. Загрузчик так же проверяет наличие тупиковых ситуаций и может быть использован как для синхронной закачки файлов, так и для асинхронной.

Если Вы не соблазнились написанным выше – не переживайте. Новая система классов абсолютно совместима с предыдущими версиями. Ваши старые классы, созданные при помощи Ext.extend, все равно будут работать и мы будем продолжать создавать файл ext-all.js, содержащий всю библиотеку целиком.

Демонстрация возможностей


Мы создали очень простое демонстрационное приложение и выложили его в Интернет. Примеры начинаются с самых простых и потихоньку усложняются в дальнейшем. Собственно, пример можно скачать в виде архива и запустить на локальной машине для экспериментов: все, что Вам понадобиться – это веб-сервер для отдачи файлов.

Новая система классов – это базис для многократно улучшенной библиотеки ExtJS 4. Каждый важный класс в библиотеке был обновлен так, что бы стать быстрее, что бы разработка стала более простой и удобной. На протяжении следующих недель мы будем демонстрировать возможности наших пакетов по очереди в ожидании Ext JS 4. Следующий на очереди – наш замечательный пакет для работы с данными.
Tags:
Hubs:
Total votes 35: ↑28 and ↓7+21
Comments20

Articles