Шаблоны AJAX в ASP.NETИсточник: cyberguru
При сравнении с парадигмой разработки, согласно которой создается огромное большинство современных веб-приложений, очевидно, что AJAX представляет серьезный сдвиг этой парадигмы для архитекторов веб-решений. Он полагается на несколько новых принципов и правил для объяснения поведения веб-систем и требует некоторых новых алгоритмов для их применения. Основным принципом AJAX является отправка простых данных на веб-сервер и получение новых простых данных. Вторым принципом AJAX является самостоятельное управление операциями, обходящее размещающий обозреватель и его механизмы одностраничного запроса/ответа. Третьим принципом AJAX является полная ответственность клиентского кода за обновление интерфейса пользователя с использованием простых данных, получаемых от сервера. Эта статья заложит фундамент для разработчиков, готовых полностью отойти от консервативного применения AJAX, представленного частичной визуализацией. Частичная визуализация - это способ получить часть функций AJAX, продолжая опираться на архитектуру веб-форм. Парадигма AJAX основана на новых принципах, требующих новых шаблонов разработки. Влияние парадигмы AJAXЧастичная визуализация ASP.NET - это искусное добавление поверх классической модели обратной передачи веб-форм. По сути, страница, использующая частичную визуализацию, имеет ту же архитектуру обратной передачи и жизненный цикл, что и страница, не использующая AJAX (см. рис. 1). Далее, разница лежит в перехватчике на стороне клиента, который просто предотвращает действие обозревателя по умолчанию - подачу формы - и заменяет его на ведомый XMLHttpRequest запрос HTTP (см. рис. 2). Этот трюк позволяет пользователю не обновлять страницу полностью, в то же время экономя разработчику время на изучение новой архитектуры и новых шаблонов.
Рис. 1 Традиционная операция полной обратной передачи страницы
Рис. 2 Частичная визуализация XMLHttpRequest AJAX Не стоит и говорить, что частичная визуализация предоставляет графические преимущества в контексте текущей страницы. Но если приложение разработано на основе собрания отдельных страниц, переход с одной страницы на другую все же требует полной загрузки страницы. Частичная визуализация отлично заменяет внутристраничные обратные передачи, такие как подкачку таблиц, корректировку интерфейса пользователя после изменения выбора или изменение записи на месте. Поскольку частичная визуализация - просто более интеллектуальная форма обратной передачи страницы, она страдает от общих архитектурных ограничений модели. Например, на каждое окно обозревателя можно иметь лишь один ожидающий запрос. В нынешней модели веб-приложений (подал форму, получил новую страницу) это ограничение может и не быть большой проблемой. Однако после расширения горизонтов с помощью AJAX становится нормальным ожидание одновременного выполнения пользователем нескольких действий. Имея одну лишь частичную визуализацию, пользователь не может одновременно запустить две асинхронные операции и ожидать, что обе завершатся. Частичная визуализация ограничена одной операцией запроса за раз с целью предохранения единообразий состояния представления - остающегося интегральной частью модели. А это противоречит смыслу первой буквы A в AJAX: асинхронности. При частичной визуализации возможны внешние обратные передачи под управлением JavaScript, но лишь по одной за раз. Если вторая операция запускается до завершения первой, отложенная операция отменяется, чтобы могла выполниться новая. Модель, при которой приоритет отдается последнему, можно программно изменить на модель, где приоритет отдается первому и текущая операция остается активной, тогда как новая проглатывается системой - но от факта возможности не более одной операции за раз никуда не деться. Модель одностраничного интерфейсаЧтобы в полной мере воспользоваться AJAX, все компоненты, или по крайней мере большинство из них, должны находиться на одной странице. Это называется моделью одностраничного интерфейса (SPI). В модели SPI все взаимодействия обозревателя с веб-приложением происходят в пределах одной страницы. Это революционный подход для Сети, но обычный в разработке для Windows® и рабочих сред. В конечном счете, модель SPI в точности подобна приложению Windows с основным (и единственным) окном. В модели SPI основная страница является сочетанием визуальных элементов, которые можно загружать, обновлять и заменять независимо друг от друга (см. рис. 3). Таким образом, нет нужды в перезагрузке всей страницы после действия пользователя. В любой конкретный момент отображаются только визуальные элементы и содержимое, относящиеся к текущей стадии работы приложения. Все остальное скрыто, оно будет показано, когда это понадобится процессу приложения.
Рис. 3 Элементы одностраничного интерфейса внутри страницы Модель SPI естественным образом делает возможными целый ряд высокоинтерактивных функций, включая изменение на месте, зависящий от контекста интерфейс пользователя, немедленные запросы отзыва пользователя и асинхронные операции. Но основным преимуществом модели SPI является не производительность или скорость ответа, а значительное повышение удобства работы пользователей. Но, не забывая об этом множестве преимуществ, следует знать, что разработка новых приложений под модель SPI является серьезной задачей, поскольку для нее не существует устоявшегося набора шаблонов и рекомендаций. В конечном счете, существует простой способ применить AJAX, подходящий для большого числа компаний и случаев. И, вдобавок, не такой уж простой, но также укореняющийся сейчас, способ применить AJAX. Для создания чистых приложений AJAX необходимая хорошая библиотека элементов интерфейса пользователя для предоставления эффектов и специальных поведений. Необходима насыщенная и настраиваемая объектная модель документов (DOM), использующая стандартную модель DOM консорциума WWW W3C) в качестве нижележащего механизма, но позволяющая пользователю определить собственную модель для конкретного приложения. Наконец, необходима платформа сервера и клиента для быстрой разработки пользовательского интерфейса и вспомогательных сценариев. В идеале, следует также иметь средства для отладки и тестирования всего этого. Корпорация Майкрософт и другие поставщики предоставляют некоторые из этих частей. Имеется несколько библиотек с элементами оформления интерфейса пользователя, из которых можно выбирать, и есть поставщики, производящие элементы управления, которые определяют собственные объектные модели на стороне клиента. Здесь могла бы серьезно помочь улучшенная платформа AJAX, специально разработанная как альтернатива веб-формам и вдохновленная моделью SPI. Одной из таких альтернативных моделей программирования является инфраструктура модель-представление-контроллер (MVC), которую можно найти в библиотеке расширений ASP.NET 3.5. Но в своей текущей форме она мало чем может поделиться с AJAX, и, поскольку она не делает ненужной реализацию любой из функций AJAX, то не кажется разработанной с расчетом на эволюцию в модель SPI. Но посмотрим, что будет дальше. В модели SPI основная страница указывает на конечные точки HTTP в том же приложении. Она исполняет удаленный код, но не перезагружает всю страницу. Кроме того, она обновляет интерфейс пользователя, используя элементы управления, создающие и HTML, и сценарий. И эти элементы управления могут быть достаточно "умными" для создания большей части требуемого ими кода JavaScript. Например, представьте себе форму, используемую для заказа билета на самолет, с двумя возможными параметрами для поиска: временем или стоимостью. Если пользователь более заинтересован в самом дешевом авиарейсе, то нет нужды отображать раскрывающийся список с часами. Если пользователю нужно вылететь в определенное время, то необходимо создать код HTML, отображающий часы. Очевидно, что этот фокус с показом/сокрытием можно легко проделать, применив немного кода JavaScript. Однако в наше время разработчик страницы несет ответственность за написание этого кода. Элементы управления, такие как элемент управления CollapsiblePanel из библиотеки ASP.NET AJAX Control Toolkit (asp.net/AJAX/AjaxControlToolkit/Samples/CollapsiblePanel/CollapsiblePanel.aspx), также могут проделать это. Недостатки модели одностраничного интерфейсаХотя модель SPI и предоставляет более интерактивное обслуживание пользователя, она и воплощенная в ней парадигма AJAX сопряжены с рядом проблем, включая возможность поиска, управление журналом, доступ и поддержка автономного режима. Веб-страницы отслеживались с использованием постоянных ссылок не один год. Поисковые механизмы выстроили свой бизнес путем простого сопоставления набора ключевых слов с одним или несколькими URL-адресами. Эта модель работала, основываясь на предположении, что каждое состояние в веб-приложении соответствует странице и определенному URL-адресу. С появлением модели SPI в AJAX это предположение более не верно. Если всё (или хотя бы основная работа) происходит внутри одной страницы, то смены URL-адреса, отмечающего новое состояние и новое содержимое веб-узла, не происходит. Как следствие, не существует простого способа связать содержимое (и ключевые слова) с уникальными URL-адресами. Этот аспект модели SPI влияет на возможность поиска, а также на управление журналом (скажем, на возможность использовать кнопки "Назад" и "Вперед"). Журнал обозревателя может со временем стать устаревшей концепцией, тесно привязанной к классической, статической модели Интернета. Тем не менее, следует помнить, что пользователи настолько привыкли к этим кнопкам, что их нельзя просто отключить. Доступность - еще одна большая проблема приложений AJAX. Для большинства популярных программ озвучивания текста любое содержимое, созданное сценариями модели DOM, создает огромные сложности. По своему замыслу все формы AJAX, включая частичную визуализацию, в большой степени основаны на сценариях модели DOM. Следовательно, доступности необходимо добиваться другими средствами. Раздел 508 руководства по доступности содержимого Интернета (Web Content Accessibility Guidelines - WCAG) рекомендует, чтобы страницы предоставляли альтернативный функциональный текст, который может быть прочтен вспомогательной технологией, каждый раз, когда они используют языки сценариев для отображения содержания или создания визуальных элементов. Тег <noscript> существует для обеспечения выполнения этой рекомендации. В настоящий момент большинство инфраструктур AJAX производят свои динамические обновления внутри страницы, не обновляя статическую информацию, содержащуюся в тегах <noscript>. Функционально насыщенные приложения Интернета со специальными возможностямиПроблема кажется состоящей из двух частей, которыми являются как приложения AJAX, так и технология в основе озвучивателей текста. С одной стороны, существуют озвучиватели текста, которые понимают некоторые из клиентских событий, таких как onclick, keypress и readystatechange. Способность озвучивателя текста замечать эти события может оказаться достаточной, чтобы добавить, по крайней мере, первый уровень специальных возможностей для большого числа приложений на основе AJAX. С другой стороны, озвучиватели текста обычно не говорят никакой новой информации, если они зашли далее события первоначальной загрузки страницы в DOM. Но существуют некоторые фокусы, которыми можно воспользоваться, чтобы сообщить озвучивателю текста об изменении в чем-либо. Один из наиболее эффективных включает установку tabindex на -1 в корне обновленного древа DOM. Однако это простой фокус, и специальные возможности заслуживают более широкого решения на основе AJAX. Возможным решением является новый стандарт, разрабатываемый в W3C и именуемый стандартом функционально насыщенных приложений Интернета со специальными возможностями (ARIA), который в основном состоит из относящихся к озвучивателям тегов HTML. Несколько популярных клиентских библиотек AJAX уже поддерживают некоторые компоненты ARIA. Но если смотреть более широко, проблема состоит не только в наличии совместимого с AJAX стандарта специальных возможностей. Проблема лежит также, если не в особенности, в содержимом (разметке и сценарии), реально создаваемом серверными элементами управления. И как насчет автономных приложений? Многие разработчики считают, что автономные приложения AJAX невозможны, поскольку приложения AJAX строго привязаны к Интернету. С моей точки зрения, это мнение чересчур упрощено, но не ложно в целом. В наше время, почти все веб-приложения - AJAX или не AJAX - основаны на Интернете или интрасетях. Но приложения, не использующие AJAX, определенно могут работать в автономном режиме. Например, в случае управления журналом всю функциональность, делающую возможными переходы в автономном режиме, содержит обозреватель. В классических веб-приложениях каждый запрос HTTP управляется обозревателем. Если подключение недоступно (и перед созданием ошибки HTTP 404), обозреватель просматривает локальный кэш страниц. Приложение AJAX отличается от классического веб-приложения тем, что оно использует объект XMLHttpRequest вместо механизма обозревателя для отправки запросов HTTP. Чтобы приложения AJAX поддерживали автономные сценарии, нужно просто дать объекту XMLHttpRequest либо доступ к кэшу обозревателя, либо способность создавать собственный кэш посещенных страниц и управлять им. Эта возможность начинает появляться в составе некоторых платформ AJAX. Однако это нетривиальное изменение, поскольку оно требует доступа к диску изнутри кода JavaScript. Краткий обзор шаблонов AJAXСледующий этап эволюции веб-приложений ведет напрямую к AJAX и, говоря в общем, к функционально насыщенным приложениям Интернета (RIA). На переднем фронте этой эволюции находятся три категории приложений: классические веб-узлы на основе HTML, гибридные приложения, созданные для интеграции нескольких систем в один веб-интерфейс пользователя, и "толстые" клиенты. Для первой категории частичная загрузка интерфейса пользователя (частичная визуализация) представляет собой легкий способ применения AJAX с минимальным воздействием на существующий код и навыки. Концепция гибридности, с другой стороны, не обязательно пригодна для AJAX и улучшенного взаимодействия с пользователями. Это просто способ сбора данных с широкого набора источников и совмещения их в единообразном и цельном интерфейсе пользователя. Это также может произойти в классическом варианте "от сервера к серверу". Однако AJAX делает это проще и, честно говоря, лучше. С точки зрения AJAX, гибридному приложению нужны стандартные форматы сериализации данных (сведения), облегченная платформа для вызова удаленных служб через сценарий, обновляемая модель DOM, и, возможно, несколько функционально насыщенных визуальных элементов управления с удобной моделью программирования. Самой сложной задачей является создание "толстых" клиентов с помощью AJAX. "Толстый" клиент может быть пользовательским интерфейсом для распределенной корпоративной системы или, возможно, уровнем представления бизнес-приложения. Он также может быть независимым приложением, которое отдел ИТ решил предоставить как веб-приложение. Эти приложения, опубликованы ли они в Интернете или ограничены интрасетью, нуждаются в возможностях и скорости стандартного интерфейса пользователя в форме рабочего стола. По сравнению с развитием Windows веб-приложения являются шагом назад в плане интерактивности и скорости ответа. С появлением AJAX у разработчика наконец появились средства (и необходимые условия) для развития в направлении существенно отличающейся модели. Но ради этого приходится идти на значительные жертвы. С одной стороны, существуют миллионы пользователей и разработчиков, привыкших к старой сети и ее парадигмам журнала, автономных переходов, избранного, единых операций, переходов страниц и постоянных ссылок. С другой стороны, есть AJAX и его парадигма одновременных операций и единого, автоматически обновляющегося интерфейса пользователя. В данном случае модель AJAX требует реальной модели отмены действия для задач пользователя, в отличие от простого использования функций журнала и перемещения по страницам обозревателя. Для создания кода в модели SPI необходим новый набор шаблонов разработки. На рис. 4 перечислены некоторые из наиболее популярных шаблонов AJAX. Как можно заметить, в большинстве из них основное внимание уделено приемам и расположению интерфейса пользователя, хотя стоит сказать, что в список не входят некоторые популярные шаблоны и практические рекомендации по AJAX, которые уже реализованы в клиентской библиотеке Microsoft® AJAX. Например, уже нет нужды в создании заглушки AJAX, независимой от обозревателя модели JavaScript или модели отслеживания вызовов, - если используется AJAX для ASP.NET, то все эти функции доступны изначально. Рис. 4 Некоторые шаблоны AJAX
Следует также заметить, что шаблоны, перечисленные на рис. 4, и шаблоны AJAX в целом являются скорее справочными шаблонами, чем шаблонами разработки. Они указывают распространенные способы работы, но не все из них соответствуют проблемам разработки. На рис. 4 я кратко описал суть каждого шаблона. В оставшейся части статьи я намерен углубленно рассмотреть некоторые из этих шаблонов. В будущих статьях я вернусь к другим важным шаблонам, чтобы рассказать о том, что ими движет, и продемонстрировать некоторые практические применения. (Отличным веб-узлом для пополнения знаний о шаблонах AJAX является ajaxpatterns.org.) Шаблон уникального URL-адреса
URL-адреса - это суть Интернета. Пользователи сохраняют избранные URL-адреса на будущее, следуют по URL-адресам к новому содержимому и используют URL-адреса для возвращения к предыдущему состоянию. С помощью AJAX и модели SPI приложение может выполнить ряд задач изнутри одного URL-адреса, а это угрожает подрубить центральную основу работы в Интернете: то, что отдельные состояния приложения идентифицируются отдельными URL-адресами. Обозреватели создают свои кэши URL-адресов по мере перемещений пользователей. Но в случае AJAX многие операции не проходят через обозреватель и не кэшируются в списке посещенных URL-адресов, на основе которого работают меню "Назад" и "Вперед". С другой стороны, клиентские обозреватели не предоставляют программной модели для добавления URL-адресов к списку с помощью кода JavaScript. Объектная модель обозревателя предоставляет лишь методы для перемещения назад и вперед внутри существующего списка. Шаблон уникальных URL-адресов назначает уникальный и выразительный URL-адрес каждому значительному состоянию приложения. Например, если пользователь щелкает для изменения значения на странице AJAX, новый URL-адрес должен быть добавлен к кэшу обозревателя, хотя операция и была произведена через XMLHttpRequest внутри одной страницы. Изменить URL-адрес без перезагрузки страницы можно при помощи следующего кода JavaScript: window.location.hash = stateInfo; Этот код добавляет к URL-адресу фрагмент с префиксом #, как показано ниже: http://www.contoso.com/shopping.aspx#edit-1234 При использовании этого шаблона URL-адрес реально изменяется при запуске любой конкретной операции AJAX, что позволяет обозревателю отслеживать изменения в состоянии приложения. Однако дело не сводится к простой записи URL-адреса. Когда обозреватель направляется на URL-адрес на основе хэш-кода, он сперва загружает основной URL-адрес, а затем ищет фрагмент страницы с кодовым именем. В контексте AJAX кодовое имя указывает не на фрагмент реальной страницы, а на относящуюся к приложению информацию, представляющую текущее состояние. Например, edit-1234 может означать, что изменяется элемент с идентификатором, равным 1234. Конкретный формат целиком управляется программистом. Если обозреватель не может найти верный фрагмент, он просто игнорирует хэш-код в URL. Как следствие, у пользователя загружается страница, но не обязательно в ожидаемом состоянии приложения. Необходим второй фокус. Следует перехватить событие onload страницы, проанализировать URL-адрес, извлечь хэш-код и выполнить код JavaScript, необходимый для помещения страницы в желаемое состояние, вот так: window.onload = function() { Похожий подход применяется в поддержке журнала, имеющейся в расширениях ASP.NET 3.5. Получить дополнительные сведения об этом можно по адресу quickstarts.asp.net/3-5-extensions/ajax. Решение в расширениях ASP.NET 3.5 полностью интегрировано в платформу. Его можно увидеть в форме новых свойств и событий, добавляемых к элементу управления ScriptManager. Но в итоге оно остается реализаций шаблона уникальных URL-адресов. Вдобавок, следует обратить внимание, что фокус, основанный на хэш-коде в URL-адресе, не работает в Internet Explorer®, поскольку Internet Explorer не распознает изменения хэш-кода для URL-адреса, кроме как для встроенных кадров. На самом деле, у всех обозревателей есть свои особенности в обработке перехода по фрагментам (см. weblogs.asp.net/bleroy/archive/2007/09/07/how-to-build-a-cross-browser-history-management-system.aspx, чтобы получить дополнительные сведения по этой теме). Решение в расширениях ASP.NET 3.5 разбирается с этими особенностями, что и позволяет квалифицировать его как независимое от обозревателя. Шаблон времени ожиданияОдним из крупнейших преимуществ AJAX является возможность применения обновлений страницы в реальном времени. Однако обновления в реальном времени могут стать серьезной опасностью для приложения в случае злоупотребления ими. Представьте себе случай, в котором пользователь отображает постоянно обновляющуюся страницу, каждые несколько секунд запрашивающую сервер, чтобы обновить то или иное содержимое. Предположим, что пользователь оставляет ее на несколько часов, не отключая обозреватель. Как следствие, страница продолжает отправлять запросы, создавая значительную и бесполезную нагрузку на сервер. Как можно определить, что сеанс клиента истек? На сервере существует время ожидания сеанса, но в AJAX имеет значение также сеанс клиента. Чтобы обнаружить завершение сеанса клиента, необходимо проверить, производил ли пользователь какие-либо действия вроде щелчков и нажатий в течении определенного периода времени. Отслеживание активности клавиатуры и мыши может требовать много ресурсов; облегченный и более простой подход, основанный на таймерах, обычно более эффективен. Чтобы обнаружить завершение сеанса при помощи таймера, установите таймер клиента, истекающий через установленное число секунд (или, что более вероятно, минут), который останавливает текущую задачу и выводит окно предупреждения. Если пользователь отвечает на запрос, обработка возобновляется как обычно. На рис. 5 показан фрагменты кода JavaScript, иллюстрирующий суть шаблона времени ожидания. Образец страницы внедряет часы. Часы добываются с помощью элемента управления Label ("Метка") в UpdatePanel, который периодически обновляется элементом управления Timer, вот так: Рис. 5 Применение времени ожидания сеанса клиента<script type="text/javascript"> Часы представляют собой ресурсоемкую задачу, которая может затопить сервер запросами. Идея в том, чтобы установить таймер, периодически запрашивающий пользователя, действительно ли он желает продолжать работать с часами. Код времени ожидания сперва останавливает часы и затем отображает окно сообщения. В зависимости от ответа пользователя часы перезапускаются. Код использует функцию $find для обнаружения компонента AJAX для ASP.NET - в данном случае это будет объектная модель клиента, принадлежащая серверному элементу управления ASP.NET Timer ("Таймер"). На рис. 6 показана страница в действии со всплывающим окном, запрашивающим пользователя, можно ли продолжать.
Рис. 6 Запрос пользователя, можно ли продолжать Дино Эспозито (Dino Esposito) - автор книги Programming ASP.NET 3.5 Core Reference ("Справочник по основам программирования в среде ASP.NET 3.5"). Проживая в Италии, Дино часто выступает на различных отраслевых мероприятиях по всему миру. |