Казахстан, Алматы, Гимназия им. Ахмета Байтурсынова №139, 2008 |
Создание динамического наполнения страницы. JavaScript-библиотеки и технология Comet
13.2.2. Построение веб-интерфейсов
Библиотека ExtJS написана на JavaScript и работает во всех популярных сейчас браузерах (хотя и с некоторыми различиями), предназначена для создания сложных и насыщенных интерфейсов, которые очень похожи на аналогичные desktop-программы [5, 6]. Она предоставляет разработчику целый набор графических компонентов, от тривиальных кнопок и расширенных элементов обычных HTML-форм, до сложных компонентов вроде таблиц, лейаутов (layout – компоненты, отвечающие за расположение объектов друг относительно друга) и деревьев. В библиотеке также есть достаточно много невидимых пользователю компонентов, которые и обеспечивают работу того, что пользователь видит на экране. Это и получение данных с сервера в фоновом режиме (в формате JSON или XML), обновление частей страницы, локальные хранилища данных, поддержка cookie и многое другое.
Самым мощным и известным компонентом является таблица или Grid. Он позволяет выполнять группировку, сортировку и пейджинг данных (а при установке некоторых пользовательских расширений также поддерживается фильтрация), поддерживает различные виды выделения данных. Также Grid предоставляет возможность редактировать данные, причем при установке некоторых расширений, этот компонент позволит не только редактировать данные в строках, но и будет автоматически создавать всплывающие формы.
Каждый компонент в ExtJS позволяет себя конфигурировать путем настройки разнообразных опций, генерирует множество событий в ответ почти на любое изменение своего состояния, а также гибко настраивается через задание необходимых свойств оформления в CSS-стилях.
13.2.3. Использование CSS
В архитектуре библиотеки есть и такое понятие как тема оформления – это обычный CSS-файл, изменяя который можно мгновенно изменить внешний вид всех элементов интерфейса. Уже создано множество различных пользовательских тем, в разной цветовой гамме и стиле, хотя, на мой взгляд, именно стандартная тема наиболее приятная и привычная для большинства пользователей.
13.2.4. Основные компоненты и возможности
Для рассмотрения библиотеки ExtJS можно разделить ее компоненты на несколько групп.
Самый нижний слой – это низкоуровневые функции по работе с DOM-деревом, событиями, стилями и другие функции. Здесь можно использовать адаптеры для подключения нескольких библиотек. В особенности это нужно, когда необходимо смешать в одном приложении функциональность, к примеру, jQuery и ExtJS. Во последних версиях ExtJS можно использовать как родные функции, так и другие библиотеки: jQuery, Yahoo UI!, Prototype.
Core – это основные базовые модули и функционал, который необходим для работы всех остальных компонентов библиотеки и приложения. Он разбит на несколько модулей:
- Ядро – это обязательный компонент, обеспечивает общий менеджер событий, работу с адаптерами и основные операции с DOM-моделью. Для построения самых простых приложений можно использовать только этот компонент, так как в него включены все необходимые функции, в том числе и UpdateManager для обновления любой части страницы по расписанию или событию от пользователя.
- Для использования визуальных компонентов (виджетов) нужен модуль, который обеспечивает их работу, рендеринг и управление наборами виджетов. ExtJS поддерживает функции отложенного рендеринга (lazy render) когда все операции по отрисовке или обновлению элементов координируются самой библиотекой, а это экономит время и делает приложение быстрее.
- Утилиты – добавляют функции работы с JSON, обработку CSS, работу с событиями клавиатуры и базовую поддержку шаблонов.
- Поддержка кросс-браузерного Drag&Drop вынесена в отдельный модуль (нужен, если используются виджеты).
- Возможность хранить состояние интерфейса в независимом хранилище, например cookie (компонент State Manager ) – при повторном входе все открытые окна или вкладки в браузере будут восстановлены.
Работа с данными. Так как любое веб-приложение основано на каких-то данных, то этот слой в библиотеке не менее насыщенный различным функционалом, чем визуальные компоненты. Обмен данными с сервером может вестись в двух форматах – JSON, как самый простой для JavaScript, и XML, что позволяет реализовать более широкий функционал, но за счет увеличения ресурсоемкости всего приложения.
Вся работа с данными построена на следующей компонентной схеме:
- основной компонент Store – с ним и работают другие объекты, желающие получить или отправить данные;
- Reader отвечает за структуру данных и их верную интерпретацию, вне зависимости от формата;
- Proxy обеспечивает прозрачный доступ к серверу через промежуточную абстракцию Connection так, что приложению не важно, да и не надо даже знать, как в реальности данные пришли от сервера;
- объект (или набор объектов) Record хранит коллекцию записей из данных (согласно заданной структуре).
Исходя из нужного функционала, можно использовать компоненты, которые работают с JSON -данными или XML, или и те и другие вместе.
13.2.5. Визуальные компоненты
Помимо замещения всех стандартных для форм элементов, ExtJS предлагает и более крупные "строительные блоки" для приложения в целом.
Управление общей компоновкой обеспечивают компоненты группы Layout, которые позволяют разметить блоками всю область окна приложения и в дальнейшем работать с ними по отдельности, обеспечивая в то же время общую целостность интерфейса и его структуры (рис. 13.1). Отдельные части страницы можно сворачивать, скрывая полностью или менять их размер, передвигать границы областей – все, что привыкли делать пользователи в обычных приложениях.
Динамическая подсказка или Tooltip – позволяет для любого элемента на странице (как визуального, так и к любому DOM-объекту) прицепить подсказку, которая будет показана при наведении мыши. Сама подсказка может содержать в себе произвольный HTML-код, изображения и даже быть контекстно-зависимой – подгружаться через AJAX.
При необходимости можно подключать и использовать множество виджетов – кнопки (разного вида, с изображениями и текстом, кнопки-переключатели, кнопки с выпадающим меню и т.п.), меню (как контекстные, так и тулбары с меню, совсем как в обычных приложениях), индикаторы загрузки и прогресс-бары. Есть и такое, свойственное только Веб-приложениям решение, как Loading Mask, которое позволяет "заморозить" для пользователя все приложение на то время, пока получаются и обновляются данные с сервера. Есть и функциональные компоненты для выбора даты и цвета, есть компоненты для вывода сообщений, как модальные MessageBox, так и полноценные окна, в которые, в свою очередь, можно вставлять любые элементы управления или разделять их закладки, сворачивать и развертывать, перетаскивать по экрану и т.п.
Таб-панель – еще один мощный компонент для построения тех приложений, которые, с одной стороны, требуют, чтобы пользователю показывалось сразу много разной информации, формы, таблицы и другие объекты, в то же время нужны ограничения, и в каждый момент времени показывать только самое необходимое. Для такого структурирования широко применяют вкладочный интерфейс. Даже диалоговые окна в ExtJS имеют свойства для автоматического преобразования набора правильно оформленных DIV-слоев сразу в набор панелей.
Tree – часто используемый компонент, позволяющий группировать иерархические структуры и отображать их с любой глубиной вложенности, автоматически подгружая новые элементы, менять местами, перетаскивая мышью отдельные элементы и другие стандартные операции (рис. 13.2). В последних версиях деревья были расширенны путем добавления функций редактирования элементов прямо на месте отрисовки (Inline item editing).
Форма является одной из основных высокоуровневых абстракций библиотеки, и использует почти все из описанных компонентов, в частности большинство визуальных виджетов, которые расширяют стандартные элементы форм. Она также использует слой доступа к данным для заполнения некоторых компонентов (например, ComboBox может получать данные от сервера). В функциональность форм входит и предварительная проверка вводимых пользователем значений, что уже стало классической функциональностью для Веб. Используя встроенные обработчики, можно проверять вводимые e-mail адреса, URL и просто строки символов, однако никто не мешает расширять встроенные наборы, создавая пользовательские валидаторы (любой виджет для ввода данных позволяет определить произвольную функцию для проверки ввода). Есть и встроенный HTML-редактор. Форма в ExtJS сама умеет передавать себя на сервер в виде XML-документа и обрабатывать ответ, в том числе и валидацию полей на сервере – для этого есть отдельный компонент, стандартно же и спользуется JSON и обычная передача через GET/POST параметры.
Таблица Grid – самый востребованный и самый мощный из компонентов, которым располагает разработчик на ExtJS (рис. 13.3). Впрочем, он одновременно является и самым сложным. В общих чертах, он также построен на модели абстракции каждого уровня: данные могут получаться из DataStore, внешнее отображение задается как специальными функциями-рендерами для каждого столбца отдельно, так и компонентом GridView, который отвечает, например, за заголовок таблицы и создание тулбара с элементами постраничного управления выводом данных. Для выделения строк и ячеек есть, соответственно, RowSelectinsModel и CellSelectionModel. Также поддерживается особый тип таблиц со встроенной функцией редактирования данные напрямую в ячейке (это позволяет расширить функционал такой таблицы почти до уровня Excel/Calc). В версии ExtJS 2.0 появилась возможность избирательно группировать строки, совмещая, таким образом, функционал ьность таблицы и дерева (Grid и Tree). Конечно, в таблице пол ностью поддерживается и Drag'n'Drop – можно визуально менять расположение столбцов, перетаскивать отдельные строки, менять их ширину, сортировать данные в колонках и другие операции.
Развитие библиотеки не стоит на месте. Например, вместе с выходом среды Adobe AIR библиотека пополнилась отдельным интерфейсом, позволяющим легко взаимодействовать с этой средой и встраивать ее возможности в приложение. Таким образом, совместно с AIR и ExtJS можно реально создавать приложения, которые, оставаясь веб-ориентированными, вместе с этим просто идентичны традиционным "десктопным", совмещая все преимущества и сильные стороны обоих типов программ.
13.3. Библиотека Prototype
Prototype – JavaScript -фреймворк, упрощающий работу с Ajax и некоторыми другими функциями [7]. Несмотря на его доступность в виде отдельной библиотеки, он обычно используется программистами вместе с Ruby on Rails, script.aculo.us и Rico.
Заявлено, что данный фреймворк поддерживается следующими браузерами: Internet Explorer 6.0+, Mozilla Firefox 1.5+, Apple Safari 2.0+ и Opera 9.25+.
13.3.1. Возможности
В Prototype присутствуют самые разные способы упрощения создания JavaScript -приложений, от сокращенного вызова некоторых функций языка до сложных методов обращения к XMLHttpRequest. Ниже приведены некоторые примеры.
13.3.1.1. Функция $()
Для обращения к DOM элементу HTML-страницы обычно используется функция:
document.getElementById: document.getElementById("id_of_element")
Функция $() уменьшает код до [8]:
$("id_of_element")
Но в отличие от функции DOM, функции $() можно передавать более одного аргумента и функция вернет массив ( Array ) объектов со всеми соответствующими элементами:
var ar = $('id_1', 'id_2', 'id_3'); for (i = 0; i < ar.length; i++) { alert(ar[i].innerHTML); }
Например, для указания цвета текста можно использовать следующий код:
$("id_of_element").style.color = "#ffffff";
Или, используя расширенные функции Prototype:
$("id_of_element").setStyle({ color: '#ffffff' });
Код для версий ниже 1.5:
Element.setStyle("id_of_element", { color: "#ffffff" });
13.3.1.2. Функция $$()
Функция $$() используется для разделения CSS от контента. Она разбивает один или несколько CSS фильтров, которые поступают на вход в виде выражения подобного регулярному выражению и возвращает элементы, которые соответствуют этим фильтрам. Например, при выполнении данного скрипта:
var f = $$('div#block .inp');
получим массив, содержащий все элементы с классом .inp, которые находятся в контейнере div с идентификатором id="block".
13.3.1.3. Функция $F()
Похожая на $(), функция $F() возвращает значение определенного элемента HTML формы. Для текстового поля функция будет возвращать данные, содержащиеся в элементе. Для элемента "select" функция возвратит выбранное в текущий момент значение:
$F("id_of_input_element")
13.3.1.4. Функция $A()
Функция $A() преобразует один аргумент, который она получает, в объект Array. Эта функция, в сочетании с расширениями для класса Array, облегчает конвертирование или копирование любых перечислимых списков в объект Array. Один из вариантов использования заключается в том, чтобы преобразовать DOM NodeLists в регулярные массивы, которые могут быть более эффективно использованы.
13.3.1.5. Функция $H()
Функция $H() преобразовывает объекты в перечислимые Хэш-объекты, которые похожи на ассоциативный массив:
//Допустим имеем объект: var hash = { method: post, type: 2, flag: t }; //При использовании функции: var h = $H(hash); //Получим: alert(h.toQueryString()); //На экране будет отображено: post&type=2&flag=t
13.3.1.6. Объект Ajax
Объект Ajax предоставляет простые методы инициализации и работы с функцией XMLHttpRequest, без необходимости подстраивать код под нужный браузер. Существует два способа вызова объекта: Ajax.Request возвращает XML вывод AJAX -запроса, в то время как Ajax.Updater помещает ответ сервера в выбранную ветвь DOM.
Ajax.Request в примере ниже находит значения двух полей ввода, запрашивает страницу с сервера, используя значения в виде POST -запроса, а после завершения выполняет пользовательскую функцию showResponse():
var val1 = escape($F("name_of_id_1")); var val2 = escape($F("name_of_id_2")); var url = "http://yourserver/path/server_script"; var pars = { value1: val1, value2: val2 }; var myAjax = new Ajax.Request( url, { method: "post", parameters: pars, onComplete: showResponse });
13.3.1.7. Класс Element
Методы класса предназначены для работы с элементами HTML. Для создания HTML элемента используется конструктор класса:
new Element(tagName[,{attributes}])
В конструктор передается HTML-тег в строковом виде и, если необходимо, атрибуты тега.
Пример создания нового элемента:
// Создаем элемент <div> в памяти и указываем атрибуты id, class var newElement = new Element('div',{id: 'childDiv', class: 'divStyle'}); // Включаем созданный элемент в DOM браузера, а именно в существующий <div> с помощью метода Element.insert Element.insert($('parrentDiv'),newElement);