Применение Веб-методов. Технология Jasp
14.2. Технология Jasp
14.2.1. Введение
Jasp является библиотекой для разработки Веб-приложений с использованием платформы Microsoft .NET Framework [9, 10]. Основным отличием Jasp от ASP.NET является ориентация библиотеки на клиентскую сторону, чтобы программисту было проще создавать "богатый" пользовательский интерфейс в первую очередь средствами языка JavaScript, CSS и в последнюю очередь HTML, сгенерированным на стороне сервера (как это часто бывает при разработке на ASP.NET ). Такие приложения зачастую состоят из небольшого количества страниц (чаще всего одной), и все необходимое подгружают по мере использования без перезагрузки страницы. Примером таких приложений могут п ослужить сервисы: GMail, Google Maps, Pusk.ru и другие.
Основной недостаток ASP.NET заключается в сложности разработки клиентских компонент (использующих JavaScript ).
Рассмотрим простой пример: предположим, на странице необходимо вводить дату, и в целях экономии места на странице было решено сделать текстовое поле с выпадающим вниз календарем. Есть два пути решения: создать наследника UserControl, и наследника WebControl. У каждого из вариантов есть плюсы и минусы. В первом случае несомненным плюсом является возможность создания разметки, скриптов и стилей прям в ASCX-файле, но при этом данный компонент нельзя использовать в других проектах (только если копировать код из одного проекта в другой). Во втором случае нет ASCX-файла, а все дочерние компоненты приходится создавать программно. С другой стороны такой компонент можно использовать повторно.
В обоих случаях, при реализации клиентской части компонента возникает ряд проблем:
- всегда необходимо передавать ClietnID компонента в JavaScript -код, что конечно возможно, но не всегда удобно;
- приходится следить за загрузкой связанных с компонентом ресурсов: изображений, стилей и вспомогательных JavaScript -файлов;
- вместо отсутствующей клиентской части компонент есть простой набор вызовов и несколько объявлений JavaScript -функций.
Обобщим все возможные проблемы, при создании компонент на классическом ASP.NET:
- Различные трудности, возникающие при связи серверной и клиентской части компонента, в результате которых зачастую на клиентской стороне получается не полноценный объект с набором свойств и методов, а набор строк JavaScript -кода, с которым, нельзя работать как с одним объектом.
- Огромный размер ViewState. Есть плюсы его использования, но чаще всего (особенно при использовании красивых и функциональных сторонних компонент ), он достигает таких больших размеров, что из-за него страдает производительность, даже если его хранить на сервере.
- Использование ASP.NET Ajax зачастую приводит к непредсказуемым результатам. ViewState пересылается при каждом, пусть и асинхроном PostBack'e, даже там, где это не нужно, что в свою очередь не очень хорошо сказывается на производительности;
- Ресурсы , загружаемые с помощью WebResource.axd. Порой на одной странице их скапливается довольно много, тем самым, осложняя жизнь браузеру. К тому же не все браузеры способны одновременно загружать несколько ресурсов на страницу.
- При большой вложенности компонент получаем огромные ClientID, что плохо сказывается на результирующем размере HTML разметки, а иногда приводит к полной неработоспособности страницы.
- Нет возможности полноценного наследования компонент (включая клиентскую сторону или HTML разметку).
- При создании WebControl'ов создание дочерних компонент приходится делать вручную.
- При создании UserControl'ов, их нельзя использовать в других проектах.
Технология Jasp пытается решить все указанные проблемы. Компонент Jasp одновременно является как серверным (разработка в ключе классического ASP.NET ), так и клиентским ( JavaScript - компонентом ). Каждый компонент можно использовать и в других проектах (даже имеющий разметку и собственные ресурсы ) без всяких изменений. Присутствует возможность наследования, как серверной части, так и клиентских частей: JavaSctpt, CSS и разметки. Все ресурсы загружаются автоматически и по мере использования (синхронно или асинхронно). При первой загрузке страницы загружаются только необходимые ресурсы, оптимизирова нные и сгруппированные в несколько файлов. Jasp можно использовать со всеми распространенными JavaScript -библиотеками: jQuery, ExtJS, Prototype и т.п.
14.2.2. "Hello World" на Jasp
Создание нового приложения на Jasp ничем не отличается от создания обычного ASP.NET приложения. Можно даже не создавать новый WebSite/WebApplication, а использовать существующий. Главное, чтобы был добавлен Reference на сборку Jasp и присутствовали минимальные необходимые настройки в web.config для работы Jasp:
<configuration> <configSections> <section name="jaspSettings" type="Jasp.Configuration.SettingsSection"/> </configSections> <jaspSettings /> <system.web> <httpHandlers> <add verb="*" path="*.jasp" type="Jasp.Web.HttpHandler, Jasp"/> </httpHandlers> </system.web> <system.webServer> <handlers> <add name="JaspCommonHandler" path="*.jasp" verb="*" type="Jasp.Web.HttpHandler, Jasp" resourceType="Unspecified" preCondition="integratedMode"/> </handlers> </system.webServer> </configuration>
Для создания страницы необходимо создать класс, унаследованный от класса Jasp.Web.UI.Page. Имя класса должно совпадать с именем страницы.
Создадим страницу, выводящую "Hello world!".
using Jasp.Web.UI; using Jasp.Web.UI.HtmlControls; namespace Jasp.Examples { public class HelloWorld : Page { protected override void OnInit() { Body.Controls.Add(new Literal("Hello world!")); } } }
Чтобы зайти на страницу, вводим в браузере /HelloWorld.jasp. Пока не будем углубляться в детали сгенерированного HTML, а просто убедимся, что все работает – в браузере увидим "Hello world!", и при загрузке страницы не произойдет JavaScript -ошибок.
14.2.3. Создание страницы с разметкой, скриптом и стилями
Рассмотрим пример создания страницы, содержащую разметку, скрипты и стили.
Для примера, создадим страницу, текст которой будет анимирован с помощью эффектов jQuery. Для начала, добавим в проект JavaScript -файл jquery-1_2_6_min.js с библиотекой jQuery (в любое место проекта). Не забудем установить Build action в embedded resource (подробнее подключение ресурсов описывается ниже). Данный файл будет являться общим ресурсом для всех страниц или компонент.
Далее создадим класс для страницы, назовем его Example1:
using Jasp.Resources; using Jasp.Web.UI; namespace Jasp.Examples { [Resources("jquery-1_2_6_min.js")] public class Example1 : Page { } }
Добавим классу атрибут ResourcesAttribute с указанием имени файла с jQuery. Теперь, при загрузке страницы, Jasp будет добавлять этот файл к скриптам страницы.
Теперь создадим CSS файл Example1.css со стилями для текста страницы:
.text-style { color:red; font-weight:bold; font-size:large; }
Также создадим файл Example1.htm с разметкой, содержащий текст, который будет анимироваться:
<html> <head> <title>Пример 1</title> </head> <body> <span id="text">Анимированный текст!</span> </body> </html>
Теперь создадим JavaScript -файл Example1.js с кодом, который будет анимировать текст:
{ // функция, вызываемая при инициализации контрола $init: function(){ // указатель на текущий контрол var self = this; // дожидаемся инициализации jQuery jQuery(document).ready(function(){ // запускаем анимацию self.animateText(); }); }, // функция для анимации текста animateText: function(){ // указатель на текущий контрол var self = this; // производим анимацию jQuery(self.$text.$dom).toggleClass('text-style').toggle(1000, function(){ self.animateText(); }); } }
После загрузки страницы, мы увидим мигающий текст.
Рассмотрим, каким образом Jasp подгружает CSS и JavaScript файлы.
14.2.4. Ресурсы в Jasp
При загрузке страницы, Jasp определяет, какие ресурсы используются на странице: это может быть HTML-разметка, один или несколько CSS или JavaScript файлов. Jasp группирует все CSS и JavaScript файлы в один CSS и один JavaScript файл и добавляет специальные ссылки в HTML разметку, по которым они подгружаются браузером:
<script type="text/javascript" src="?$scripts=7_5_2_3_4_6_&v=-1720007920"> </script> <link rel="stylesheet" type="text/css" href="?$styles=&v=-1720007920" />
По-хорошему, у всех страниц сайта должна быть одна базовая страница (аналог MasterPage ), содержащая одинаковый набор базовых стилей и скриптов. Таким образом, данные ресурсы "закэшируются" и для других страниц сайта.
Страницы могут отличаться набором компонент, которые на них расположены. При загрузке страницы Jasp также определяет, какие ресурсы используют все компоненты, расположенные на странице. HTML каждого компонента подставляется в соответствующее место в результирующий HTML, а все CSS и JavaScript файлы, по аналогии с ресурсами страницы, объединятся в один CSS и один JavaScript файл.
<script type="text/javascript" src="?$pageScripts=2_&$r=&v=-1720007920"> </script> <link rel="stylesheet" type="text/css" href="?$pageStyles=2_&$r=&v=-1720007920" />
У каждой страницы или компонента могут быть как личные ресурсы, которые подгружаются автоматически и могут использоваться только данным компонентом, или его наследниками, так и общие, которые могут использоваться сразу несколькими компонентами. Личные ресурсы должны называться также как имя класса компонента (без учета расширения). Естественно, ресурсы компонент, которые изначально не используются на странице, загружены не будут. Их загрузка произойдет автоматически при первом использовании.
14.2.4.1. CSS ресурсы
Зачастую в проектах бывает один или пару CSS файлов, в которые без разбора добавляются все стили из всего проекта, даже если стиль используется один раз для определенного элемента. Такой файл получается довольно большим и трудно поддерживаемым. В Jasp можно создать общий файл, куда поместить основные стили, а стили, специфичные для определенных компонент или страниц, помещать в личные CSS-файлы компонент.
Необходимо отметить, что Jasp подменяет клиентские идентификаторы компонент – поэтому стили с селекторами через идентификаторы работать не будут.
14.2.4.2. JavaScript ресурсы
JavaScript ресурс – это текстовый файл с расширением js, содержащий JavaScript -код компонента. Данный файл должен определять один единственный объект – экземпляр компонента. В простейшем случае это пустой объект:
{ }
Если в объекте определена функция $init, то она будет вызвана сразу же после вызова клиентского конструктора (конструкторы создаются автоматически и подменять или модифицировать их нельзя):
{ $init: function(){ // код инициализации } }
Также в контексте данного объекта могут быть определены и другие функции компонента.