Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ajax_v_deystvii.pdf
Скачиваний:
34
Добавлен:
05.03.2016
Размер:
5.83 Mб
Скачать

106 Часть I. Новый взгляд на Web-приложение

осталась такой же, как и в листинге 2.11. Мы лишь заменили обращения к консоли на вызовы функций onload и onerror. Эти действия также могут показаться несколько непривычными для многих разработчиков, поэтому мы рассмотрим их подробнее. Функции onload и onerror представляют собой объекты Function, a Function.call() — это метод данного объекта. Первый параметр, Function. call (), представляет собой контекст функции, и в теле функции на него можно ссылаться с помощью ключевого слова this.

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

function myCallBacM ) { alert(

this . url

+" loaded! Here's the content:\n\n" +this.req.responseText

);} Очевидно, что, для того, чтобы написать код объекта, подобного рас-

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

Данный пример демонстрирует преимущества реструктуризированной программы. Мы "спрятали" внутри объекта сложные фрагменты кода, представив потенциальному пользователю внешние элементы, при работе с которыми не возникает трудностей. Фрагменты, разобраться с которыми может только квалифицированный специалист, теперь изолированы от остальной части программы. Если возникнет необходимость модификации кода, она будет выполнена локально, и не придется анализировать всю программу в поисках фрагментов, в которые надо вносить изменения.

Мы рассмотрели лишь основные принципы реструктуризации и их использование на практике. В следующем разделе мы обсудим более сложные проблемы, возникающие при создании Ajax-программ, и выясним, как можно решить их, используя ту же реструктуризацию. Попутно мы опишем ряд полезных приемов, которые будем применять в следующих главах и которые смогут помочь вам при работе над собственными проектами.

3.2. Варианты применения реструктуризации

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

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

Глава 3. Управление кодом Ajax 107

3.2.1- Несоответствие браузеров: образы разработки Fagade и Adapter

Спросите любого разработчика Web-приложений, какие проблемы он считает главными, и каждый, будь он программистом, дизайнером, художником или специалистом другого профиля, ответит, что в первую очередь необходимо обеспечить корректное отображение данных различными браузерами. Большинство вопросов функционирования Web регулируется стандартами, и производители браузеров в основном пытаются следовать им. Однако иногда стандарты допускают разночтение, что отражается в их реализации; в некоторых случаях производители расширяют стандарты в удобном для себя направлении, кроме того, в браузерах, как и в любых сложных программах, всегда есть ошибки.

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

Обработка элементов DOM

Как было сказано в главе 2, Web-страница представляется JavaScriptпрограмме в виде древовидной структуры DOM, элементы которой соответствуют элементам HTML-документа. При обработке дерева DOM из программы часто возникает необходимость определять позицию элемента в окне браузера. К сожалению, производители браузеров уже давно предоставляют для этой цели нестандартные методы, затрудняя перенос кода из одной клиентской программы в другую. В листинге 3.2 показан упрощенный вариант одной из функций библиотеки Майка Фостера (подробнее о ней — ниже, в разделе 3.5). Эта функция выполняет все необходимые действия для определения позиции левого края компонента страницы, соответствующей DOM-элементу е, который передается в качестве параметра.

Листинг 3.2. Функция getLeft (} function getLeft(e){ if(!(e=xGetElementById(e))){ return 0;

}

var css=xDef(e.style);

if (ess && xStr(e.style.left)) { iX=parselnt(e.style.left); if(isNaN(iX)) iX=0;

}else if(ess && xDef(e.style.pixelLeft)) { iX=e.style.pixelLeft;

}

return iX;

}

В различных браузерах предусмотрены разные способы определения позиции, соответствующей узлу DOM. В стандарте CSS2, разработанном W3C, описано свойство style . left . Его значением является строка, содержащая

108 Часть I. Новый взгляд на Web-приложение

числовую величину и единицы измерения, например ЮОрх. Поддерживаются не только пиксели, но и другие единицы. Свойство style.pixelLeft, напротив, допускает указание только числа; при этом предполагается, что значение задано в пикселях. Данное свойство поддерживается только Microsoft Internet Explorer. Метод getLef t (), рассматриваемый здесь, определяет, поддерживаются ли CSS, а затем проверяет оба значения, начиная с того, которое предусмотрено стандартом W3C. Если ни одно из значений не найдено, метод возвращает нулевую величину, предусмотренную по умолчанию. Заметьте, что здесь не определяется имя и версия браузера, а применяется более надежный способ обнаружения объектов, который рассматривался в главе 2.

Написание подобных функций, учитывающих особенности каждого браузера, — рутинная и утомительная работа, но после ее окончания программист может продолжать написание приложения, не уделяя внимания конкретной проблеме. Существуют библиотеки, авторы которых уже выполнили необходимую работу. Готовые надежные функции для определения позиции элемента DOM и решения других подобных задач могут существенно ускорить создание пользовательского интерфейса для Ajax-приложения.

Обращение к серверу

О проблеме несовместимости браузеров мы уже говорили в главе 2. Производители клиентских Web-программ предоставляют нестандартные средства получения объекта XMLHttpRequest, используемого для организации асинхронного взаимодействия с сервером. Если мы хотим скопировать XML-документ с сервера, необходимо решить, какое средство использовать для этого.

Internet Explorer выполняет необходимые действия только в том случае, если мы обратимся к компоненту ActiveX, а в браузерах Mozilla и Safari для этой цели используется встроенный объект. Об этих различиях "знает" только фрагмент кода, отвечающий за загрузку XML-документа. Как только программа получит объект XMLHttpRequest, она будет работать независимо от того, какое именно решение реализовано в конкретном браузере. Код, обращающийся к объекту, не должен зависеть от того, используется ли ActiveX или подсистема браузера. Все, что ему надо, — это конструктор net.ContentLoader().

Образ разработки Facade

Как для getLeft(), так и для new net.ContentLoader() код, предназначенный для обнаружения объектов, сложен, и создавать его утомительно. Определяя функцию, скрывающую его, мы делаем остальную часть программы эолее простой для восприятия. В этом состоит базовый принцип реструктуризации — не повторяться (don't repeat yourself — DRY). Если окажется, что код, предназначенный для обнаружения объектов, работает некорректно, ошибку надо будет исправить в одном месте, а не искать, где в программе эпределяются координаты элемента DOM или формируется запрос.

Глава 3. Управление кодом Ajax

109

Рис. 3.1. Условное представление образа разработки Facade, используемого для работы с объектом X M L H t t p R e q u e s t на различных браузерах. Функция loadXML () лишь использует объект X M L H t t p R e q u e s t и не "заботится" о его реализации. Сама реализация может быть очень сложной, но вызывающей функции предоставляются только базовые элементы

Другими словами, поступив подобным образом, мы используем образ разработки Facade, который предоставляет одну точку доступа к функциональным средствам, реализованным различными способами. Например, объект XMLHttpRequest обеспечивает полезные возможности, а использующее его приложение не должно "заботиться" о том, как они реализованы (рис. 3.1).

Во многих случаях бывает необходимо упростить доступ к подсистеме. Например, при получении координаты левого края элемента надо учитывать, что CSS позволяет задавать значения в пикселях, пунктах, дюймах и других единицах измерения. В нашем случае такое разнообразие представлений лишь затрудняет работу. Функция getLeft (), приведенная в листинге 3.2, применима лишь до тех пор, пока в качестве единиц измерения используются пиксели. Упрощение подсистемы — это еще один результат, достигаемый посредством образа разработки Fagade.

Образ разработки Adapter

С образом разработки Fagade непосредственно связан образ Adapter. В этом случае мы также работаем с двумя подсистемами, выполняющими аналогичные функции. В качестве примера можно привести варианты получения объекта XMLHttpRequest в продуктах Microsoft и Mozilla. Вместо того чтобы

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]