Archive for the ‘extjs’ Category

Немного про ExtJS

Май 14, 2010

Надо сказать, что я не использовал ExtJS около полутора лет. За это время сменился мажорный номер версии (на 3) и у библиотеки добавилось приятных возможностей, которые упрощают жизнь. Самым значительным изменением для меня стала доступность Ext.data.Writer, который сильно облегчает задачу сохранения данных. Вообще заметно, что библиотека становится все более зрелой и фишко-насыщенной. Но, одновременно со всем этим, у нее остались теже проблемы, которые меня всегда в ней немного раздражали. При всей ее зрелости, любой шаг вправо-влево от того, что предлагает библиотека все так же карается расстрелом, багами и жестокими оверрайтами, которые потом вылезают боком. Я, конечно, соглашусь с теми, кто скажет, что я просто не умею ее готовить и с любой библиотекой так получается. Но весь прикол как раз в том, что для того, чтобы эффективно писать на ExtJS, надо с ней жить =) Т.е. тратить значительное строить и строить на ней приложения, запоминать хлипкие куски и знакомые паттерны багов и так далее. А что-то не хочется. А теперь немного речей от моего внутреннего героя Стэна, который в очередной раз многое понял.

Про архитектуру приложений на ExtJS написано уже достаточно много (раз, два на вскидку), я ничего добавлять не буду. Для собирающих модулей я предпочитаю, так называемый Revealing Module Pattern, который является продолжением идей Yahoo про Module Pattern, но по структуре мне нравится больше. А так все тоже, создаем свои компоненты, наследуя из от экстовских и оживляем их =)

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

Довольно часто сталкиваешься с тем, что обновив ExtJS что-то перестает работать. В первую очередь, надо следить за тем, что вы обновили плагины, которые входят в поставку ExtJS (например RowEditor). Затем надо проследить, что все внешние плагины обновлены. Если ничего не помогло, то стоит отправится на форум. Часто там уже вовсю обсуждают, как починить вашу проблему =), потому что она не только ваша. Ну и потом уже можно вооружаться FireBug и писать на форум.

Вот список самых интересных плагинов, с которыми я работал в этот раз:
Ext.ux.form.DateTime — позволяет выбирать дату и время, а не просто дату.
Ext.ux.form.GroupingCombobox — позволяет использовать группировку значений, как обычный <optgroup>.
Ext.ux.form.XCheckbox — в отличие от обычного чекбокса, всегда отправляет значение, вне зависимости от того, отмечен он или нет.
Ext.ux.grid.CheckColumn — позволяет делать колонку из чекбоксов
Ext.ux.grid.ItemDeleter — добавляет колонку по нажатию на ячейки которой можно удалять строки
Ext.ux.grid.RowEditor — из официальной поставки, удобно редактировать строки в гриде
Ext.ux.gird.Search — старый-старый плагин, который позволяет осуществлять поиск по разным колонкам грида
Ext.ux.PanelCollapsedTitle — плагин, который добавляет заголовки на свернутые панели BorderLayout (причем и для IE, и для остальных вменяемых браузеров)
Ext.ux.grid.Filter — семейство фильтров, который вешаются в меню колонки и позволяют не загромождать тулбар всякими поисковыми формами

Обо всем по-немногу. Firefox, AMR, ExtJS.

Февраль 28, 2008

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

Сегодняшняя заметка будет очень короткой, но информативной. Посмотрим на пару улучшений, которые я давно хотел описать

Конвертация AMR и 3gp.

Я часто пользуюсь диктофоном на мобильном телефон. Во-первых, потому что не всегда есть возможность достать бумагу и ручку, а во-вторых для того, чтобы хранились логи встреч, которые потом можно послушать, если забыл что же было решено по итогам встречи 😉

Я не помню уже, чем конвертировал из amr в mp3 под Windows, но под *nix искать программу долго не пришлось. Попробовав несколько самопальных скриптов, некоторые из которых опасны для жизни файлов 😉 я остановился на программе Mobile Media Converter (ссылка внизу страницы, между гуглоРекламой, долго искал =). Программа с самым банальным интерфейсом и тем очень удобна. Умеет работать с amr и 3gp, а большего мне и не нужно.

Знаменитый баг Firefox

С этим багом я столкнулся сразу же после установки Ubuntu. Это тот самый знаменитый баг, из-за которого хоткеи не работают в русской раскладке. Его уже поправили (за деньги), но исправления будут только в Firefox 3. А пока, необходимо установить маленький add-on, который всё вам поправит. И будет шастье =)

Небольшой багФикс для ExtJS

Замешивая полный винегрет из тем, упомяну ещё одну вещь. Все знают, что ExtJS можно заставить говорить по-русски в окошках/менюшках, просто подключив файл с русской локалью. Но в нем есть один неприятный и редкий баг. При работе с DateField, когда выставляется формат содержащий месяц прописью (янв, фев и пр.), мы получаем январь 1970 года и ничего кроме.

Вся проблема кроется в массиве Date.monthNumbers, в котором содержатся неверные короткие имена. Надо просто заменить его на следующий:

Date.monthNumbers = {
  Янв : 0,
  Фев : 1,
  Мар : 2,
  Апр : 3,
  Май : 4,
  Июн : 5,
  Июл : 6,
  Авг : 7,
  Сен : 8,
  Окт : 9,
  Ноя : 10,
  Дек : 11
};

На сегодня — всё. Надеюсь, что скоро станет посвободнее и я допишу туториал по ExtJS и гридам с фильтром и поиском =)

ExtJs. Многостраничный грид с фильтром и поиском. Часть 1.

Январь 23, 2008

Просматривая статистику поискового трафика, любезно предоставленную мне feedburner’ом, я замечаю, что основная масса трафика идет на тему ExtJS. Мне не совсем понятен этот момент 😉 Обычно, когда мне что-то надо узнать по ExtJs, я двигаю на их форум. Потому что именно там собрана вся информация, которая вообще может пригодиться (после документации, конечно). В гугле я ищу только конкретные ошибки, которые выдает мне FireBug. Потому что поисковая система форума далека от идеала.

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

Работая с ещё с ExtJS 1.1, я нашел замечательный топик, в котором рассказывалось о подобном гриде. И приводился замечательный пример. В этом примере всё отлично. Но он написан на первой версии и использует в качестве бэк-энда python. В этой серии туториалов я опишу создание такого же грида, с использованием ExtJS 2.0, php5 и Oracle (для MySQL будут приведены примеры запросов, не сильно отличающиеся от ораклинских).

В этой заметке я лишь опишу примерную структуру будущего виджета, а в дальнейшем приведу код с комментариями и пояснениями.

Итак. Наш грид будет состоять из:

  • grid.html — html-файл, содержащий разметку страницы
  • grid_data.php — файл, обслуживающий запросы к БД со стороны грида
  • grid.js — js-файл, содержащий основной код приложения

Архитектура будет банальной. Наш грид посредством AJAX-запросов, будет обращаться к php-файлику и тот будет передавать ему данные в формате JSON. Запросы к БД будут всего двух типов:

  • Запрос очередной страницы с данными
  • Поисковый запрос

Для простоты демонстрации, не будем сильно усложнять поиск и обойдемся LIKE. Но никто не мешает реализовать сложную поисковую логику. Просто это выходит за рамки этой серии статей. Ну а постраничная разбивка — это совсем просто (хотя на Oracle — чуть сложнее)

На сегодня всё. Stay on line.

ExtJs. Один запрос, несколько Ext.data.Store.

Ноябрь 28, 2007

Не так давно я рассказывал о библиотеке ExtJs, ей же будет посвящена сегодняшняя заметка. Эта заметка расчитана на подготовленного читателя, который уже разобрался с базовыми понятиями. Но и новичку будет полезно взглянуть на то, что предлагает эта библиотека, возможно захочется стать подготовленным =) Комментарии будут подробными.

Стоит заметить, что речь пойдет о второй версии, которая сейчас значиться Release Candidate 1 и доступна для скачивания по ссылке

Сегодня речь пойдет об Ext.data.Store. Объект удачный и используется во множестве виджетов в качестве источника данных. Обычный подход заключается в том, чтобы создать подгружающий себя объект и вызывать метод load(), для его загрузки.

//Инициализируем соединение
var rCon = new Ext.data.Connection({
    //Урл "кормящего" файла =)
    url:    '/data.php',
    //Метод
    method: 'POST',
    //Параметры, которые передадутся в запросе
    extraParams: {'act' : 'get_requests'}
});
//Само хранилище
var rDs = new Ext.data.Store({
    //Прокси с соединением, созданным выше
    proxy: new Ext.data.HttpProxy(rCon),
    //"Читатель" ответов, приходящих в формате JSON
    reader: new Ext.data.JsonReader({
        //Какое свойство читать
        root: 'requests',
        //Какое свойство отвечает за кол-во записей
        totalProperty: 'total_requests',
        //Поля записей
        fields: [
        'requests_key',
        'requests_name'
        ]
    })
});
rDs.load();

Так выглядит обычное создание и загрузка хранилища. При вызове метода load() идет асинхронных запрос к серверу, получаются данные и далее с ними делается то, что нужно. Вcё замечательно. Есть одно «но». Хранилище в силу своей универсальности используется и для ComboBox — выпадающих списков в формах. А этих самых ComboBox в одной форме может быть много. У меня, например 19 =) Таким образом, реализуя приведенную выше схему, мы получим 19 асинхронных вызовов. А это не очень хорошо.

Известно, что у браузеров есть ограничение на количество одновременных вызовов. Благодаря комментариям, мы знаем, что это 3 для FF и 2 для IE. И мы получаем сильное снижение производительности. Это если не брать в расчет проблемы с обработкой 19 вызовов, и синхронизации загрузки с отображением. Ведь если не успеют загрузиться хранилища, а мы уже начнем показывать форму, будет не очень красиво.

Продумав это всё в голове, я пришел к выводу, что надо действовать по-другому. Надо наполнить все 19 хранилищ за один запрос. Поиски на форуме не привели к нахождению решения. Хотя пару идей я получил. В рецепте, приведенном ниже будет использован метод loadData(), вместо load(). Который просто загружает уже пришедшие данные в хранилище, никуда не обращаясь. Я не буду приводить код для 19 хранилищ, приведу для двух.

//Создаем record. Пригодится для "читателя" хранилища.
dsDataRecord = new Ext.data.Record.create([
//Пишем название свойства и мапим его
//на второй элемент массива пришедших данных
{name : 'data_key', mapping : 1},
{name : 'data_name', mapping: 2}
]);
//Хранилище номер раз.
dataStore = new Ext.data.Store({
    //Читатель на этот раз "массивный" а не JSON =)
    reader: new Ext.data.ArrayReader({
        //Первый элемент массива для упорядочивания. Он уникальный.
        id: 0
        //Наш record.
    }, dsDataRecord)
});

//Создаем record. Пригодится для "читателя" хранилища.
dsDigitRecord = new Ext.data.Record.create([
//Пишем название свойства и мапим его
//на второй элемент массива пришедших данных
{name : 'digit_key', mapping : 1},
{name : 'digit_name', mapping : 2}
]);
//Хранилище номер два.
digitStore = new Ext.data.Store({
    //Читатель на этот раз "массивный" а не JSON =)
    reader: new Ext.data.ArrayReader({
        //Первый элемент массива для упорядочивания. Он уникальный.
        id: 0
        //Наш record.
    }, dsDigitRecord)
});
//AJAX-запрос на все данные
comboStoreRequest = Ext.Ajax.request({
    //Урл "кормящего файла"
    url: 'data.php',
    //В случае успешного запроса
    success: function(result){
        //Преобразуем JSON-ответ в объект
        comboStore = Ext.util.JSON.decode(result.responseText);
        //Загрузим массив данных первое хранилище
        dataStore.loadData(comboStore.data);
        //Загрузим массив данных во второе хранилище
        digitStore.loadData(comboStore.digit);
    },
    //Метод
    method: 'POST',
    //Параметры вызова
    params: {act : 'get_data'}
});

Приведенный код тоже не слишком сложен. Самое интересное, для меня, было сформировать теперь выдачу с сервера JSON-данных, чтобы их «прожевал» ArrayReader. И сделал из них массивы, приемлемые для загрузки в хранилище.

На основе документации, можно прийти к выводу, что ArrayReader ожидает данные в виде объектов вида:


[[1, key1, name1],[2, key2, name2],[3, key3, name3]]

Значит в PHP нам необходимо иметь массив, повторяющий приведенную структуру и применить к нему json_encode()

<?php
//Массив с данными
$data_array[] = array(1, "data_key1", "data_name1");
$data_array[] = array(2, "data_key2", "data_name2");
$data_array[] = array(3, "data_key3", "data_name3");
//Выводим JSON-массив
echo json_encode($array);
?>

Первый пункт выполнен. Этими данными вполне можно «накормить» один ArrayReader. А у нас их два. А ответ от сервера один. Значит надо наши массивы упаковать как свойства объекта. И обращаться к ним при загрузке в хранилище. Для этого на сервере нужен следующий PHP-код:

<?php
//Первый массив
$data_array[] = array(1, "data_key1", "data_name1");
$data_array[] = array(2, "data_key2", "data_name2");
$data_array[] = array(3, "data_key3", "data_name3");
//Второй массив
$digit_array[] = array(1, "digit_key1", "digit_name1");
$digit_array[] = array(2, "digit_key2", "digit_name2");
$digit_array[] = array(3, "digit_key3", "digit_name3");
//Собираем всё в один массив.
$data = array('data' => $data_array, 'digit' => $digit_array);
//Выводим окончательный ответ.
echo json_encode($data);
?>

Готово. Теперь мы передаем JSON-объект с двумя свойствами, которые являются массивами данных. И мы можем загрузить их в наши dataStore. Задача выполнена =)

Javascript библиотека ExtJs.

Ноябрь 26, 2007

Не помню, писал ли я или нет, но в последнее время я плотно использую javascript библиотеку ExtJs. Для начала опробовал её для административной панели небольшого проекта, когда ExtJs была ещё версии 1.x. Потом применял её виджеты в frontEnd проектов покрупнее, тоже в версии 1.x. Теперь перешел на ExtJS 2.0RC1 в основном проекте. И с нетерпением жду релиза второй версии.

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

  • AJAX, интегрированный на всех уровнях, контроллируемый с небывалой легкостью.
  • Гриды (продвинутые таблички) для данных разных модификаций и видов
  • Деревья с возможностями drag’n’drop и lazyLoad (загрузка только необходимых узлов с помощью AJAX)
  • Всевозможные Layout’ы для построения как отдельных кусков страниц, так и целых приложений
  • Формы с валидацией на стороне клиента, в которые можно и подгружать данные (AJAX) и сохранять асинхронно (опять AJAX 😉

Это лишь малая часть того, что может и умеет библиотека, на странице с примерами можно всё разглядеть поподробнее. И приступать к обучению

У библиотеки достаточно крутая кривая изучения, но она оправдывает себя в полной мере. На русском языке я знаю три ресурса, которые уделяют ей внимание это:

  • Гугл-группа ru-ExtJs — наиболее объемный источник информации
  • ExtJS по-русски — один из первых сайтов по тематике на русском языке, к сожалению, редко пополняется. В последнее время это статьи из…
  • Alpha-Beta-Release Blog — блог, посвященного веб-разработке во многих её ипостасях. Довольно интересные материалы, рекомендую.

Может быть я что-то упустил, но гугл до сих пор считает, что я искал extys и всё остальное — это единичные статьи и захабренные/бобренные сссылки.

Самым главным источником информации по ExtJs можно считать форум, который, естественно, англоязычный (хотя иногда встречаются китайские треды и русский код ;). Атмосфера на форуме очень хорошая, объясняют очень понятно, код приводят и вообще замечательное сообщество в плане помощи в обучении.

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

Ну а самым продвинутым и полным источником можно считать документацию. Там есть всё, иногда даже примеры реализации =) Она всегда должна быть под рукой во время разработки. Слишком уж много методов и свойств у каждого из объектов ExtJs.

Что касается лицензии, то ExtJs придерживается достаточно распространенной в последнее время двойной политики лицензирования. Есть вариант LGPL и есть коммерческая лицензия, сопровождаемая поддержкой и прочими благами в обмен на деньги =) Выбор — это всегда приятно.