MochiKit — библиотеки на все случаи жизни
обзор MochiKit
Продолжая мысль, озвученную в анонсе к статье, отмечу, что в данный момент жизнь любого JavaScript-разработчика стала значительно проще, чем, к примеру, лет пять назад. Во-первых, потому что он стал явно больше востребован. А во-вторых, его инструментарий теперь можно пополнять хоть ежемесячно все новыми и новыми продуктами и решениями, которые выглядят одно лучше другого и не менее полезны. Правда, случаются осечки с некоторыми подобными проектами, но их на самом деле не так много, как в свое время прогнозировали ряд пессимистично настроенных экспертов, рассуждая о буме JavaScript-библиотек и AJAX-оболочек.
Детально о возможностях MochiKit в той или иной области JavaScript-программирования мы поговорим чуть ниже, а пока скажем о двух преимуществах описываемого продукта, о которых говорят в один голос и его разработчики, и пользователи, и индустриальные эксперты. Позволю себе цитату с официального веб-сайта: «MochiKit is a highly documented and well tested suite of JavaScript libraries that will help you get shit done fast». Ключевые слова здесь «highly documented» и «well tested», ибо этим может похвастаться далеко не каждая библиотека или оболочка для JavaScript.
Последнее же, о чем хотелось бы упомянуть во вступлении, — это высокий уровень масштабируемости проектов, разрабатываемых на базе MochiKit. Иными словами, использование описываемой JavaScript-библиотеки совершенно не означает полный отказ от других продуктов. При желании мы можем использовать целый комплекс решений как для клиентской, так и для серверной стороны (что, в принципе, само собой разумеющееся), если, конечно, понадобится. Кроме того, MochiKit добавляет лишь три символа в global scope (MochiKit namespace и функции compare и reduce для устранения багов JScript), избегая хакинга на основе Object.prototype.
Дальше в материале мы рассмотрим основные библиотеки MochiKit с описанием их возможностей и с краткими примерами.
MochiKit.Base
Как видно из названия, это базовая библиотека в MochiKit, на основе которой, в том числе, строятся все остальные. Но, кроме того, она предоставляет своим пользователям еще и мощную низкоуровневую функциональность. Разработчики утверждают, что создавали описываемую библиотеку, находясь под впечатлением от Python и Python standard library.
Из основных же возможностей MochiKit.Base стоит выделить следующие:
- расширенная функциональность для всевозможных сравнений (compare, registerComparator);
- расширенная representation-функциональность (repr, registerRepr);
- расширенная функциональность для JSON serialization и JSON evaluation (serializeJSON, evalJSON, registerJSON);
- простая и прозрачная adaptation-схема (AdapterRegistry);
- дополнительные функции для манипуляций с объектами и массивами (update, setdefault, extend и т. д.);
- основанное на массивах функциональное программирование (map, filter и т. д.);
- расширенная функциональность для работы с функциями (bind, method, partial).
Разумеется, многие из этих возможностей вряд ли понадобятся нам во время разработки простого веб-приложения, где большее внимание уделяется другим вещам (интерфейс, usability и т. п.), но если речь идет о действительно масштабном и сложном проекте, то без подобных функций попросту не обойтись.
MochiKit.Async
Эта библиотека отвечает в MochiKit за все необходимое для разработки полноценных AJAX-управляемых веб-приложений. Работая на MochiKit.Async, разработчики черпали вдохновение в уже всем известном продукте под названием Twisted. Однако не стоит ожидать от MochiKit.Async того же стандартного подхода, что и во многих других библиотеках, ибо здесь он немного другой.
Все построено вокруг объекта Deferred, который отвечает за все рутинные операции по созданию, получению и обработке запросов между клиентской и серверной стороной. Если схематично, то выглядит это следующим образом:
- мы создаем объект Deferred и сохраняем ссылку на него, так как она понадобится нам позже;
- затем устанавливаем условия для создания серверного запроса (создаем XMLHttpRequest и настраиваем его onreadystatechange);
- возвращаем объект Deferred.
Ответ на запрос от сервера будет получен, разумеется, не сразу, поэтому объекту Deferred нужно также сообщить название callback-функции, которая будет выполнена, как только придет серверный ответ. Это, в принципе, обычное дело для всех современных AJAX-библиотек, но авторы MochiKit.Async пошли дальше: помимо callback-функции мы назначаем еще и errback-функцию, которая будет вызвана, если во время взаимодействия с сервером произошла ошибка.
MochiKit.DOM
Каждый, кто когда-нибудь занимался разработкой более-менее серьезных и масштабных JavaScript-приложений, знает, насколько мучительно порой бывает производить комплексные (в принципе и не только комплексные) манипуляции с DOM-элементами. Знают об этом и создатели MochiKit, которые постарались создать такую библиотеку для работы с DOM, чтобы у разработчиков не возникало больше головных болей, связанных не непосредственно с их проектом, а с другими второстепенными вещами вроде совместимости методов с различными версиями браузеров и так далее.
Лучшей иллюстрацией тут станет короткий жизненный пример, в котором мы с помощью MochiKit.DOM создадим простенькую таблицу. Вот так будет выглядеть JavaScript-код:
var rows = [
["dataA1", "dataA2", "dataA3"],
["dataB1", "dataB2", "dataB3"]
];
row_display = function (row) {
return TR(null, map(partial(TD, null), row));
}
var newTable = TABLE({'class': 'prettytable'},
THEAD(null,
row_display(["head1", "head2", "head3"])),
TFOOT(null,
row_display(["foot1", "foot2", "foot3"])),
TBODY(null,
map(row_display, rows)));
Вначале мы задаем данные для основных строк нашей таблицы. Затем формируем на основе этих данных HTML-код. А уже после этого создаем HTML-код целой таблицы, причем с элементами thead и tfoot. Выглядеть результат будет следующим образом:
<table class="prettytable">
<thead>
<tr>
<td>head1</td>
<td>head2</td>
<td>head3</td>
</tr>
</thead>
<tfoot>
<tr>
<td>foot1</td>
<td>foot2</td>
<td>foot3</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>dataA1</td>
<td>dataA2</td>
<td>dataA3</td>
</tr>
<tr>
<td>dataB1</td>
<td>dataB2</td>
<td>dataB3</td>
</tr>
</tbody>
</table>
И вот так просто в MochiKit.DOM можно осуществить практически любое действие практически с любым DOM-элементом. На этом, разумеется, прелести описываемой библиотеки не заканчиваются, но рассказать о них всех не хватит и целого материала, поэтому мы двигаемся дальше.
Drag'n'drop в MochiKit |
MochiKit.DragAndDrop
Одним из современных стандартов для веб-приложений можно считать возможность использовать функцию drag'n'drop для работы с теми или иными элементами страницы. Реализаций подобной функциональности сегодня насчитывается, наверное, несколько десятков, если не больше. Создатели MochiKit взяли за основу идеи из Script.aculo.us и чуть адаптировали их под собственные нужды. Посмотрим на короткий пример.
// Создаем draggable-элемент
new Draggable('mydrag');
// Создаем droppable-элемент
new Droppable('mydrop', {
accept: ['drag-class'],
ondrop: function (element) {
alert('"' + element.id + '" was dropped at me');
}
});
Все очень просто: в MochiKit.DragAndDrop мы можем создавать объекты draggable и droppable, которые затем будут взаимодействовать друг с другом при помощи конечного пользователя. Но это еще не все: draggable-элемент на протяжении своего жизненного цикла генерирует несколько сигналов (start, drag и end), которые можно обрабатывать.
onStart = function (draggable) {
// Содержимое функции
};
connect(Draggables, 'start', onStart);
Как видно из примера, вначале мы описали функцию onStart, которую затем присоединили к сигналу start у всех draggable-элементов страницы. К слову, делается это с помощью функции connect, которая является частью другой библиотеки проекта — MochiKit.Signal. Она отвечает за обработку событий.
Встроенные в MochiKit интерпретаторы JavaScript |
MochiKit.Visual
Последняя библиотека сегодняшнего обзора называется MochiKit.Visual и отвечает за всевозможные визуальные эффекты, без которых во время разработки современных веб-приложений также трудно обойтись. Сюда относятся и базовые эффекты вроде закругления углов какого-то элемента, и более сложные и динамичные вещи. В MochiKit это все объединено в рамках одной большой библиотеки. Причем реализация закругленных углов была взята из Rico; она не требует использования внешних изображений или таблиц стилей. А многие другие визуальные эффекты были перенесены из уже упоминавшегося сегодня Script.aculo.us.
Позволю себе привести несколько коротких примеров, иллюстрирующих схему работы с MochiKit.Visual.
// Закругляем углы все элементов h1
roundClass("h1", null);
// Закругляем верхний левый угол элемента с атрибутом id со значением "title"
roundElement("title", {corners: "tl"});
// Добавляем эффект fade к элементу
fade('myelement');
Что касается количественных показателей, то различных визуальных эффектов в MochiKit.Visual достаточно много. Однако там вряд ли удастся найти что-то уж совсем экзотическое. Вообще, подобное определение верно для всех без исключения библиотек проекта: они отлично справляются с поставленными задачами, работают стабильно и не требуют каких-то особых знаний, но в то же время не предлагают своим пользователям новых высот. Иными словами, MochiKit — это действительно JavaScript-библиотеки практически на все случаи жизни, но назвать их революционными или новаторскими язык не поворачивается.