Внимание! Для
работы с этой лекцией необходимы учебные файлы,
которые Вы можете загрузить
здесь.
ColdFusion - это еще один язык сценариев на стороне
сервера, предназначенный для тех же целей, что и PHP.
Если вы
пропустили лекцию 16, то вам определенно следует
обратить внимание на параграф под заголовком "Два
сервера Вероны", чтобы получить представление о том, что
такое сценарий на стороне сервера.
Существует
несколько языков сценариев на стороне сервера, например
ASP, ASP.Net, Java Server Pages и Perl, однако в этой
книге мы рассматриваем именно PHP и ColdFusion.
Популярность PHP связана с высокой производительностью и
бесплатным распространением. ColdFusion - программа
вовсе не бесплатная, на момент написания этой книги ее
Enterprise-версия стоила $4999. Профессиональная версия
стоит $799, и это тоже немало.
ColdFusion
(CF) разработан Macromedia для серверов приложений.
Разработка приложений с помощью CF предоставляет
разработчику несколько преимуществ. В этом пакете
содержится среда быстрой разработки приложений (RAD),
позволяющая разработчику легко создавать и публиковать
веб-приложения, поскольку CF использует теговый язык
разметки, наподобие HTML. Можно сказать так: то, что вы
потратите при покупке CF, будет компенсировано
сокращением времени разработки. Приложения, создаваемые
с помощью CF, обычно занимают меньше времени, что,
несомненно, экономит деньги разработчика или целой
компании. CF очень легок в изучении, и вам не
потребуется много времени, чтобы изучить все его
особенности и научиться применять его на полную мощность.
Из этого следует, что приложения CF могут
разрабатываться быстрее, чем аналогичные продукты с
помощью ASP и PHP.
Macromedia
ColdFusion MX теперь работает с компонентами Flash
Remoting, выступающими как средства связи между Flash MX
и сервером. Компоненты Remoting в данный момент
недоступны для PHP, так что здесь необходимо применять
некоторые более старые методы.
Начнем изучение
ColdFusion
Пробную
версию ColdFusion MX можно загрузить с веб-сайта
Macromedia по адресу
www.macromedia.com/software/trial_download. Trial-период
истечет после 30 дней, пакет переключится в режим IP и
сервер CF будет доступен с IP-адреса, что позволит
разработчику тестировать приложения. CF MX можно
установить на серверах с Unix, Linux и Windows. Он также
прекрасно интегрируем как с серверами IIS, так и с
Apache-серверами. У CF MX сейчас есть отдельный
веб-сервер, который можно использовать для разработки и
тестирования. В процессе разработки приложений
рекомендуется использовать один из вышеупомянутых
веб-серверов. CF относительно прост в установке, и его
настройка не займет много временем перед началом
разработки приложений.
Имейте в
виду, что если вы используете пробную версию ColdFusion
MX на своем компьютере при работе с этой лекцией, вам
необходимо перезагрузить компьютер после инсталляции
перед тем, как непосредственно открывать CF
Administrator и начинать работу.
Для создания
CF-приложений можно использовать простой текстовый
редактор, совместимый со многими операционными системами.
Просто не забудьте сохранить ваши файлы с расширением
CFM для шаблонов FC и CFC для компонентов CF. CFC будут
рассмотрены позднее в этой лекции, когда мы затронем
непосредственно само приложение. Существует несколько
интегрированных сред разработки (Integrated Development
Environments, IDE), такие как Macromedia ColdFusion и
Dreamweaver MX. Эти программы намного облегчают
разработку благодаря подсказкам в коде и файлам справки,
объясняющим назначение различных тегов CF. Рассмотрим
вкратце синтаксис CF и его назначение.
Основы
Написание
кода CF не сложнее создания HTML-документа, и вы
убедитесь в этом, как только изучите основные моменты
работы с CF. В следующем примере показано несколько
тегов CF и их синтаксис (в приложениях в конце лекции
все будет рассмотрено подробнее). Изучив теги и их
атрибуты, можно перейти к разработке сложных
веб-приложений. Для начинающих проведем краткое
рассмотрение основных тегов CF и объясним их назначение.
Так как нам не хватит времени, чтобы рассказать обо всех
тегах, начнем с наиболее важных, но в своем дальнейшем
обучении вы можете отталкиваться от знаний, которые
получите сейчас. На прилавках магазинов есть много
хороших книг по CF, и я рекомендовал бы вам купить пару
таких книг, если вы заинтересованы в продвижении в сфере
программирования в CF.
Сначала мы
рассмотрим настройку выходных переменных на странице.
Переменные являются неотъемлемой частью программирования
и могут быть использованы для хранения чисел, строк,
массивов и структур. Чтобы установить переменную в
ColdFusion, используется тег <cfset>.
<cfset variables.subject =
"Flash Remoting">
Мы создали
переменную с именем subject, содержащую значение "Flash
Remoting". Теперь, после установки переменной, можно
вызвать ее с помощью тегов <cfoutput>.
С помощью этих тегов происходит интерпретация всего, что
находится между знаками #,
в качестве переменных.
<cfoutput>#variables.subject#</cfoutput>
Результатом
этой строки будет значение переменной
subject, которое выведется
на странице. CF поддерживает множество типов переменных.
Вот некоторые из них.
- Переменные (локальные)
- Form
- URL
- client
- cookie
- session
Очень
полезно отделять переменные по контексту, так как это
ускорит работу приложений и облегчит процесс отладки.
Если контекст не предоставляется, CF должен будет
просматривать все доступные контексты, чтобы убедиться в
существовании переменной. Также при отладке приложений,
полезно знать, что переменная идет из формы или URL,
вместо того, чтобы искать переменную в шаблоне.
Рассмотрим
простой шаблон, демонстрирующий настройку и вывод
переменной на страницу. Можно создать файл в редакторе
обычного текста, однако не забудьте сохранить его в
файле с расширением CFM. Именем файла будет
welcome.cfm.
<html>
<head>
<title>CF Example</title>
</head>
<body>
<!--- set the variable --->
<cfset subject="Flash Remoting">
<!--- output the variable --->
<cfoutput>
Welcome to the world of #variables.subject#
</cfoutput>
</body>
</html>
Имейте в
виду: переменные CF не чувствительны к регистру, как в
большинстве языков программирования, "subject" и
"Subject" в CF являются одной и той же переменной.
Теперь
нужно просто перейти на ваш локальный веб-сервер с CF и
осуществить доступ к данной странице, т.е. перейти по
адресу http://localhost/examples/welcome.cfm. На
странице вы увидите надпись "Welcome to the world of
Flash Remoting", однако сначала скажем несколько слов о
комментариях, приведенных в коде выше. Как вы уже знаете,
комментарии в HTML выглядят таким образом:
<!- комментарий ->. Их
можно использовать и в шаблонах CF, однако иногда
предпочтительнее использовать комментарии CF. В них
используется синтаксис <!--- CF-комментарий
---> (обратите внимание на три дефиса вместо двух).
Преимущество использования комментариев CF заключается в
том, что они не отображаются на странице, если
пользователь выбирает опцию отображения исходного кода
View Source. Они доступны только на серверной части при
просмотре кода. Это очень полезная возможность!
В любом
языке программирования должна быть возможность выносить
решения с использованием логики. Здесь вступает в силу
тег <cfif>. Этот тег
позволяет разработчикам выполнять специфические задачи,
например, когда пользователь делает определенный выбор
или ожидаются определенные результаты.
<cfset variables.product =
"ColdFusion">
<cfif variables.product eq "Flash">
Macromedia Flash was chosen.
<cfelseif variables.product eq "ColdFusion">
Macromedia ColdFusion was chosen.
<cfelse>
No selection was made.
</cfif>
Создав
шаблон и осуществив доступ к нему через браузер, вы
увидите надпись "Macromedia ColdFusion was chosen".
Поэкспериментировав с переменной продукта, вы увидите,
что могут генерироваться различные результаты.
В среде
разработки ColdFusion существует много тегов и функций.
Для любого действия существует свой тег или функция CF.
Вы даже сами можете написать все, что вам нужно, для
выполнения вашей работы. Следующий пример будет
относительно прост для понимания с базовым знанием
синтаксиса CF.
Сообщение дня,
реализованное с помощью ColdFusion
Мы еще раз
вкратце рассмотрим упражнение "Message of the Day",
проделанное в лекцию 16, однако на этот раз оно будет
преобразовано в формат ColdFusion. Большинство аспектов
Flash останутся теми же, за исключением того, что ссылка
на update.php сменится на
update.cfm. Из этого
следует, что метод onRelease
для кнопки сохранения будет выглядеть следующим образом.
save_btn.onRelease =
function() {
dataLoader.message = _root.message_txt.text;
dataLoader.photofile = _root.image_txt.text;
dataLoader.onLoad = checkSuccess;
dataLoader.sendAndLoad("update.cfm", dataLoader, "POST");
};
Фильм Flash
будет функционировать так же, и пользователь не заметит
изменений. Логика серверной части - та часть, которая
изменится когда мы будем передавать переменные в CF, в
нашем случае, update.cfm.
Рассмотрим необходимый код CF, который будет принимать
переданные от Flash переменные формы и сохранять их в
текстовом файле на сервере.
<cfsetting enablecfoutputonly="yes">
Тег
<cfsetting> используется
для указания CF того, что на страницу не следует
выводить никакие данные, за исключением находящегося
между тегами <cfoutput>.
Это предотвратит появление любых лишних пробелов и строк.
Flash довольно требователен к пробелам, поэтому советуем
удалить их.
<cfset path="c:\inetpub\wwwroot\">
<cfset datafile="message2a.txt">
Эти
переменные просто устанавливают путь директории на
сервере, а также имя файла, который мы будем создавать.
Не забывайте обновлять путь каждый раз, когда будете
менять расположение данных файлов на сервере.
<cfparam name="form.message"
default="">
<cfparam name="form.photofile" default="">
<cfset data = "&message=" &
urlencodedformat(form.message)>
<cfset data = data & "&photofile=" &
urlencodedformat(form.photofile)>
Теперь
установим несколько значений по умолчанию для полей
формы на случай, если они не будут переданы на страницу.
Это не критично для работы приложения, однако это
помогает предотвратить любые ошибки, возникающие при
доступе к странице напрямую из веб-браузера. Переменная
data используется для
хранения переменных из Flash, которые кодируются с
помощью функции urlencodedformat.
Полезно иметь в виду, что разработчику доступно много
функций CF. Эти функции можно найти в документации CF во
время установки, в случае инсталляции по умолчанию.
<cffile action="write"
file="#path#message2a.txt" output="#data#">
Создав
переменную данных из информации, переданной от Flash,
можно создать файл на сервере и сохранить в нем эту
информацию. <cffile>
является очень мощным тегом CF, позволяющим
разработчикам читать, создавать, обновлять и удалять
файлы в процессе работы. Файл сохраняется в директории,
указанной ранее и имеющей имя
message2a.txt. Переменная
data используется для сохранения информации из
Flash в текстовом файле.
<cfoutput>&result=Okay&</cfoutput>
Наконец,
выводим результат на страницу, которая затем загружается
во Flash. Затем появляется сообщение о состоянии,
сообщающее пользователю, что файл был успешно сохранен.
Сразу после сохранения файла пользователь может нажимать
кнопку "load" и загружать информацию из
message2a.txt.
Удаленный сервис Flash
Remoting
Flash MX
шагнул далеко вперед в предоставлении средств для
разработчиков Flash. Интеграция Flash с серверами
приложений стала еще теснее. Macromedia разработал новую
интересную возможность для интеграции: удаленный сервис
Flash Remoting. Flash Remoting облегчает разработчикам
передачу сложных данных на сервер и с сервера (в нашем
случае это CF). Теперь Flash и CF могут легко
обмениваться наборами записей и отдельными объектами.
Flash Remoting не ограничивается лишь CF и доступен для
таких платформ серверов приложений, как JRUN, .NET и
J2EE.
Служба
Flash Remoting предназначена для разработчиков,
работающих с динамическим содержимым. Она позволяет
осуществлять прямые вызовы к CF или любому серверу
приложений, на котором выполняется служба. Это также
двусторонний коммуникационный процесс, при котором
данные могут передаваться из Flash на сервер. Здесь
предоставляется возможность реализовать новый и
улучшенный способ связи с сервером, в отличие от более
старых методов, таких как getURL и loadVariables. Эти
методы нисколько не устарели, однако метод для передачи
сложных данных через Flash Remoting предпочтительнее. Он
понятнее и также обеспечивает возможность создания
компонентов многоразового использования на серверной
части.
Например,
нужно построить схему аутентификации, которую можно
использовать в различных ситуациях. Все, что надо
сделать, это построить необходимые компоненты внешнего
интерфейса, а также саму систему, которая проверяет базу
данных для подтверждения данного пользователя. Эти
компоненты можно повторно использовать в будущих
приложениях, не создавая их вновь "с чистого листа".
Связь между
Flash и сервером осуществляется через шлюз Flash gateway
- компонент серверной части Flash Remoting. Шлюз Flash
передает данные на сервер и принимает их от него и может
поддерживать сложные данные, такие как объекты и наборы
записей. Наборы записей могут передаваться только с
сервера во Flash, однако они примечательны тем, что
хорошо структурированы и помогают максимизировать
эффективность канала связи. Возможность передачи наборов
записей напрямую из CF во Flash делает минимальным любой
бесцельный обмен данными.
Flash
Remoting передает данные между Flash и сервером через
Action Message Format (AMF). AMF передается по HTTP и
предоставляет более эффективные и полезные средства
связи. На следующем рисунке показан процесс коммуникации
между Flash и сервером приложений.
Проигрыватель Flash Player на нескольких рабочих
станциях
Передача
данных осуществляется с использованием нового набора
классов ActionScript, устанавливаемых вместе с Flash
Remoting. Эти классы включают в себя следующие пункты.
-
NetServices - это
абстракция NetConnection, предоставляющая средства
коммуникации со шлюзом Flash gateway.
-
NetConnection создает
двойное соединение между Flash и удаленными службами.
-
NetDebug является
методом отладки приложений Flash и работает
совместно с NetConnect Debugger.
-
RecordSet поддерживает
объекты набора записей, возвращаемые с сервера
приложений и предоставляет различные методы доступа
и управления данными наборов записей.
-
DataGlue предоставляет
возможность присваивания объектов наборов записей
компонентам Flash UI, таким как компонент ListBox.
Эти классы
содержат много способов доступа и управления данными. На
следующем рисунке показаны доступные методы для каждого
из этих классов.
За более
детальной информацией по методам классов Flash Remoting
обратитесь к справке по ActionScript во Flash MX (Window
> Reference). Мы подробнее рассмотрим структуру кода при
изучении персонального приложения управления в следующем
параграфе.
Настройка на Remoting
В следующем
приложении используются компоненты Flash Remoting, Их
можно загрузить с сайта www.macromedia.com/software/flash/flashremoting.
Установка этих компонентов обеспечит вас необходимыми
классами ActionScript и документацией для изучения
различных классов и их методов. Как только упомянутые
компоненты будут установлены вместе с ColdFusion MX,
можно приступать к разработке приложения PMA.
Приложение PMA для
работы с контактами
Это
приложение создается для реализации примера, отражающего
интеграцию Flash/CF. Оно называется PMA (Personal
Management Application) и позволяет управлять контактами
и их информацией через веб-браузер. Мы не ограничены
лишь веб-браузером, так как фильм Flash можно
преобразовать в отдельный файл проекта. PMA
продемонстрирует всю мощь возможностей Flash и
ColdFusion MX, позволив пользователям управлять базой
данных контактов, а также информацией о них. Все это
будет объединено в базу данных Microsoft Access в целях
тестирования и демонстрации. Компоненты Flash MX будут
использоваться для расширения навыков пользователя, а
компоненты ColdFusion (CFC) - в серверной части. Это
прекрасный пример использования и интеграции новых
технологий.
Для
использования этой базы данных необходим компьютер с
установленным приложением Microsoft Access.
База данных
Для
построения полнофункционального приложения необходимо
обеспечить пользователей возможностью добавлять новые
контакты, а также обновлять и удалять имеющиеся записи
контактов. Flash будет выступать в роли
пользовательского интерфейса, отображающего контактную
информацию и позволяющего пользователю взаимодействовать
с интерфейсом. Взаимодействие можно осуществлять,
выбирая формы контакта из списка ListBox или щелчком на
PushButton для выполнения определенного действия.
ColdFusion будет поддерживать логику приложения,
запрашивающую базу данных и необходимые компоненты
серверной части.
Ключом к
созданию динамического веб-приложения является
уверенность в том, что все данные структурированы.
Посмотрите на базу данных в файле pma.mdb, который
поставляется вместе с исходными файлами, и откройте
таблицу Contacts. Эта таблица содержит контактную
информацию: имя, фамилия, адрес, адрес электронной почты
и т.д. Ниже приведена структура данных для таблицы
контактов.
id послужит
главным ключом для каждой записи контакта и будет
активно использоваться при передаче информации между
Flash и ColdFusion. Поле id будет полезным при
обновлении контактов или их удалении.
- Сохраните базу
данных pma.mdb на жестком диске.
- Перед
осуществлением какой-либо связи нужно создать имя
источника данных (DSN) в ColdFusion Administrator.
Откройте Administrator, перейдя в браузере по адресу
http://localhost/cfide/administrator/index.cfm.
- Войдя в CF
Administrator щелкните на ссылке Data Sources (под
Data & Services) и добавьте ваш DSN, которым
является pma. Не забудьте указать Microsoft Access в
ниспадающем меню Driver, после чего нажмите Add. В
следующем диалоговом окне укажите, в каком месте на
сервере находится файл базы данных.
- В этом приложении
мы будем считать pma в качестве DSN, ссылаясь на
него с помощью шаблона. Откройте текстовый редактор
и введите следующий текст.
<cfset request.dsn = "pma">
- Теперь назовите
файл Application.cfm и сохраните его в новой папке с
именем pma в корневой директории.
Можно
изменить имя папки, если это понадобится, однако, в
этом случае, не забудьте обновить шаблон
Application.cfm для
отражения изменения имени папки. Этот шаблон
устанавливает ориентированную на запрос переменную с
именем request.dsn,
доступ к которой осуществляется через CFC. Эта
переменная устанавливается в
Application.cfm как глобальная, ее можно
изменить за один раз, не обновляя остального кода в
приложении. Все запросы в приложении ссылаются на
эту переменную, которая указывает на наш файл базы
данных pma.mdb.
Если
вы хотите просто запустить имеющиеся на
компакт-диске файлы, а не создавать их с "чистого
листа", не забудьте разархивировать файлы,
содержащиеся в pma.zip
в подкаталог вашего корневого каталога. Чтобы PMA
запустилось с первого раза, файлы должны быть
расположены в директории с именем pma прямо под
вашим корневым расположением веб. Структуру
директории можно изменять, однако ActionScript
придется редактировать для указания нового
местоположения. Обсудим вкратце этот процесс.
- Если вы не хотите
изменять ActionScript, настройте структуру
директории PMA следующим образом.
Компоненты
PMA
состоит преимущественно из компонентов, которые либо
поставляются с Flash MX, либо могут быть загружены с
Macromedia Exchange для Flash по адресу
www.macromedia.com/exchange/flash. Мы используем
компоненты PushButton, ListBox и ScrollBar, каждый из
которых поставляется с Flash MX, а также компоненты
Calendar и MessageBox из Flash UI Components Set 2,
которые придется заимствовать из Exchange.
Все эти
компоненты предоставляют улучшенную функциональность и
предотвращают надобность изобретения колеса
разработчиком. Это экономит многие часы работы
разработчика при создании приложений. Как только мы
начнем рассматривать приложение, вы ближе ознакомитесь с
этими компонентами, а также с кодом, который
используется для управления ими.
Фильм Flash
- Создайте новый
фильм, сохраните его в файле pma.fla и настройте
вашу временную шкалу следующим образом.
- В слое background
нарисуйте рамки, создающие структуру для компонентов,
аналогично тому, как это показано на рисунке.
Небольшое белое поле содержит окно данных (компонент
MessageBox) со списком контактов. В левом нижнем
углу большого белого поля располагается календарь, а
в правой части элементы управления вводом и кнопки.
- Слой
nav button содержит
ссылку на приложение контактов, которая в дальнейшем
может быть дополнена, если понадобится добавить
другие приложения. В моей версии она расположена в
левом верхнем углу интерфейса.
- Слой
static text содержит
весь статический текст и поля для пользовательского
интерфейса, указанные на следующем рисунке.
- Слой
dynamic text состоит
из набора текстовых полей для ввода, расположенных в
правой части рабочего места. Они представляют собой
простые текстовые поля для вода данных, с именами
переменных first_name,
last_name,
address,
city,
state,
zip,
phone и
email, соответственно.
Под заголовком Notes добавьте текстовое поле для
ввода с именем инстанса notes.
- Наконец, добавим
компоненты.
Закончив
настройку графических элементов сайта, рассмотрим код.
Инициализация приложения
- Выберите кадр 1
слоя AS и откройте панель Actions. Добавьте файлы,
содержащие классы Flash Remoting, о которых мы
говорили ранее. Они предоставляются Macromedia при
инсталляции Flash Remoting.
#include "NetServices.as"
#include "NetDebug.as"
#include "DataGlue.as"
Красота этих выражений включения состоит в том, что
вам не нужно знать, как выглядит код внутри них,
чтобы обеспечить их работу. Нужно просто знать
необходимые методы, доступные разработчику, и их
предназначение. Это прекрасный пример создания
приложений на базе компонентов. Разработчики могут
писать необходимый код для осуществления
определенных действий и передачи их дизайнерам или
менее "продвинутым" разработчикам, которые смогут
включить код и вызвать необходимые методы. Я отнюдь
не рекламирую лентяйское отношение к
программированию, а хочу показать, что код может
быть распределен по компонентам, где применение
отделено от интерфейса. Это значит, что внутренние
действия не требуют понимания, когда доступны общие
методы и возвращаются ожидаемые результаты.
Файл
NetDebug.as не обязателен для корректной работы
этого приложения. Он в основном используется
совместно с NetConnect Debugger (Window >
NetConnection Debugger) как вспомогательный файл в
процессе отладки. Как только приложение готово к
публикации, эта строка может быть удалена или
закомментирована для уменьшения размера файла (хотя
ее размер не так уж велик).
Когда
необходимые классы Flash Remoting включены, нужно
инициализировать приложение. Это одна из наиболее
важных частей процесса, так как для начала связи с
сервером необходимо установить подключение к шлюзу
Flash. Следующие шаги описывают код, необходимый для
инициализации PMA.
- Начните с
добавления переменной inited:
if (inited == null)
{
inited = true;
Это
нужно лишь для того, чтобы код, содержащийся в
выражении if, выполнялся только один раз. После
начального запуска кода
inited устанавливается на значение
true, и код не будет
выполняться повторно до тех пор, пока браузер не
будет обновлен или пользователь не покинет PMA и
вернется в него. В данном случае это не обязательно,
так как приложение содержит только один кадр. Этот
код будет полезным в фильме, циклически
возвращающемся в последний кадр несколько раз, так
как следует избегать повторных инициализаций PMA.
- Теперь нужно
добавить несколько строк кода для установки
параметров некоторых из компонентов на рабочем месте.
// disable the save clip
since it won't be accessible
// until the user decides to add a new contact
save_mc.setEnabled(false);
// set the size of the contacts ListBox
contacts_mc.setSize(200, 120);
// set the height of the scroller
notes_scroller_mc.setSize(79);
- Здесь нужно
обеспечить поддержку начального соединения со шлюзом
Flash. URL шлюза по умолчанию, в целях тестирования,
будет ссылаться на localhost.
NetServices.setDefaultGatewayUrl
("http://localhost/flashservices/gateway");
Как
только PMA попадет в среду разработки, этот адрес
понадобится для изменения доменного имени или IP-адреса
хост-сервера. Такая мера предосторожности
предотвращает возможность осуществлять вызовы служб,
имеющихся на локальном сервере, внешними
приложениями. Метод
createGatewayConnection непосредственно
создает подключение к серверу и ожидает вызова
каких-либо служб. При вызове службы контактов
подключение сохраняется в объекте, на который в
дальнейшем будут осуществляться ссылки при вызове
методов службы.
- Сначала создайте
объект подключения шлюза, затем объект службы
контактов, указывающий на CFC контактов.
var gw =
NetServices.createGatewayConnection();
var contacts_service -
gw.getService("pma.contacts", this);
Имя
службы является ссылкой на вызываемый CFC.
Следовательно, pma.contacts соответствует компоненту
contacts.cfc,
сохраненному в директории pma
(мы сейчас создадим этот компонент). Директория pma
находится на уровне, расположенном сразу под
корневым каталогом веб. Если структура директорий
меняется, то соответствующим образом необходимо
изменить и вызовы службы. Например, если директория
pma находится по адресу
\wwwroot\flashremoting\pma\contacts.cfc, эту службу
можно вызвать так: flashremoting.pma.contacts. Это
аналогично импортированию и обращению к пакетам Java
в языке программирования Java. Мы просто заменяем
слеш "\" точкой ".".
- Наконец, вызываем
метод getAllContacts
CFC, возвращающий набор записей всех контактов базы
данных.
contacts_service.getAllContacts();
}
Получение контактов
Когда
объекты служб объявлены, можно вызывать различные методы
по мере необходимости. Так как приложение было
инициализировано, необходимо осуществить первый вызов
contacts_service.getAllContacts.
Это выражение вызывает метод
getAllContacts в компоненте
contacts.cfc, который мы
собираемся создать, и используется для передачи списка
контактов во Flash. Ниже приведена схема
коммуникационного процесса между Flash и
ColdFusion.
Проигрыватель Flash Player на нескольких рабочих
станциях
Компонент
contacts.cfc будет, по
существу, шаблоном ColdFusion
с новым типом структуры. В компоненте присутствуют
несколько методов, но доступ осуществляется только к
одному из них - getAllContacts.
- Откройте
текстовый редактор и сохраните файл под именем
contacts.cfc. Добавьте
следующий код.
<cfcomponent
name="contacts">
<!--- retrieve all contacts to send to flash and
populate listbox --->
<cffunction name="getAHContacts"
access="remote">
<cfquery datasource="#request.dsn#"
name="get_all_contacts">
select id, first_name, last_name from contacts
order by last_name asc;
</cfquery>
<cfreturn get_all_contacts />
</cffunction>
<!--- you'll stick the other component methods
here --->
</cfcomponent>
Структура CFC отличается от обычного шаблона CF с
тегом <cfcomponent>, в
котором указывается имя компонента. Функции, которые
мы будем добавлять в дальнейшем, будут располагаться
внутри этого тега.
Методы
компонента также устанавливаются с помощью тега
<cffunction>, а при
возвращении результатов используется тег
<cfreturn>. В данном
случае, создается запрос для получения всех имен,
фамилий и идентификаторов из таблицы контактов. Этот
набор записей возвращается во Flash посредством тега
<cfreturn>. Атрибут
доступа тега <cffunction>
должен быть установлен на "remote", чтобы разрешить
доступ из шлюза Flash. Если этот атрибут не
установлен, метод не сможет осуществить доступ к
приложению. Для получения более подробной информации
об атрибутах доступа воспользуйтесь документацией по
ColdFusion MX.
Flash
запрашивает службу, а CF - базу данных и возвращает
результаты. Что дальше? У каждого вызова службы есть
метод result, предназначенный для поддержки данных
или выполнения действия при получении ответа от CF.
Так как из Flash изначально вызвана служба
getAllContacts,
результаты передаются в
getAllContacts_Result. Все методы ответов
помечены с использованием имени службы со словом
_Result на конце.
- Вернитесь в фильм
pma.fla, перейдите
обратно к действиям в кадре 1 слоя AS. Теперь нужно
добавить метод
getAllContacts_Result для поддержки
результатов, получаемых от CF, и в левом верхнем
углу рабочего места расположить поле списка.
function
getAHContacts_Result (records) {
// place the recordset in the ListBox and format the display
DataGlue.bindFormatStrings (contacts_mc, records,
К"#last_name#, #first_name#", "#id#");
// handle which record is selected in the ListBox
if (contact_index == undefined) {
contacts_mc.setSelectedlndex(0);
} else {
contacts_mc.setSelectedlndex(contact_index);
}
}
Набор
записей передается из CF через шлюз Flash и
обрабатывается методом result.
Теперь нужно найти способ добавления этой информации
в компонент ListBox. Здесь мы используем класс
DataGlue (изначально
включенный в код программы). Он определенно упрощает
процесс, так как позволяет указывать, какие поля
будут использоваться для отображения в ListBox во
время установки значения для каждого поля. Метод
DataGlue.bindFormatStrings
требует следующие четыре параметра.
- Имя инстанса
ListBox, в нашем случае это
contacts_mc.
- Объект набора
записей, передаваемый от CF.
- Имена столбцов
для отображения (заключены в символы
#)
- Значение для
каждой записи (заключены в символы
#).
При работе
этот метод будет осуществлять необходимую обработку
данных и заполнять поле нужными результатами.
Реализация
взаимодействия с пользователем
До этого
момента пользователь не принимал никакого участия в
процессе. Это обстоятельство мы сейчас изменим.
Существует несколько опций для пользователя, и мы
расскажем о каждой из них. Также скажем, что порядок
методов, перечисленных в коде ActionScript, не имеет
значения. Эти методы находятся на уровне
_level10 фильма и просто
ожидают своего вызова. Структура PMA позволяет
взаимодействие с пользователем. Мы обеспечим некоторую
логику действий пользователя, так что он сможет удалять
любую запись перед добавлением новой или обновлять
запись перед добавлением нового контакта. Однако у
пользователей не будет возможности удалить запись без
получения подтверждения об удаления. С помощью такой
логики мы предотвратим пользовательские ошибки и
предоставим гибкую среду.
Будем
брать контакты из поля ListBox. При инициализации PMA
код сначала устанавливает первую запись, выбранную в
поле списка, и вызывает обработчик изменений. Метод
обработки изменений вызывается каждый раз, когда ListBox
изменяет состояние. Для ListBox указывается обработчик
изменений getSelectedContact.
Обработчики изменений для различных компонентов
устанавливаются в Property inspector. Ниже в качестве
примера приведен наш ListBox.
Выбор контактов
- Метод
getSelectedContact
вызывается каждый раз, когда контакт выделяется в
списке ListBox. Добавьте следующую функцию для
запроса CF на информацию о контакте.
function
getSelectedContact() {
// if the save button is enabled go ahead and disable it
if(save_mc.getEnabled()) {
save_mc.setEnabled(false);
}
Проверяем, включена ли кнопка
save, и выключаем ее, если это так. Это
просто мера предосторожности, предназначенная для
предотвращения всплывания окна подтверждения
save, что может
произойти при нажатии кнопки.
- Теперь нужно
получить уникальный идентификатор из списка ListBox
с помощью метода getValue
и затем передать его соответствующему методу CFC.
// get the id of
the selected contact
var id = contacts_mc.getValue();
// create an object and store the id to pass to CF
var o = new Object();
o.id = id;
// set the contact index variable so we know where
// to position the ListBox when it's refreshed after
//updating
contact_index = contacts_mc.getSelectedIndex();
contacts_service.getSelectedContact(o);
}
- Для
последовательности вызываем метод CFC
getSelectedContact
обратно в файле contacts.cfc.
Этот метод запрашивает таблицу контактов и вставляет
информацию о контакте согласно идентификатору. Код
здесь очень прост и приведен ниже. Он должен быть
расположен под функцией
getAllContacts, созданной ранее.
<!--- retrieve the
selected contact and return it to flash --->
<cffunction name="getSelectedContact"
access="remote">
<cfargument name="id" default"0" required="true"
/>
<cfquery datasource="#request.dsn#"
name="get_selected_contact">
Кselect first_name, last_name, address, city,
state, zip, email,
Кphone, notes, birth_date from contacts where
id=#flash.id#;
</cfquery>
<cfreturn get_selected_contact />
</cffunction>
Id установлен как
обязательное поле с помощью тега
<cfargument> в CFC.
Этому полю также присвоено значение 0 по умолчанию,
в целях предотвращения ошибки, в случае, если не
будет передан номер id.
Как только информация о контакте запрашивается из
базы данных, она возвращается во Flash через шлюз с
помощью тега <cfreturn>.
Как
упоминалось ранее, мы используем метод
_Result для
обеспечения обработки ответа сервера. Здесь
устанавливается метод
getSelectedContact_Result, чтобы взять
данные, переданные с сервера, и разместить
соответствующие значения в текстовые поля ввода для
отображения.
- Возвращаясь к
фильму Flash, мы сначала обращаемся к записи с
помощью метода getItemAt.
Так как возвращается только одна запись, мы
осуществляем доступ к индексу 0.
function
getSelectedContact__Result(records) {
// since only record is being returned we access it at the 0
//index
var curr_record = records.getItemAt (0);
- Ссылка на эту
запись хранится в переменной
curr_record. Теперь можно осуществлять доступ
к контактным данным, переданным от CF, и размещать
их в наших текстовых полях на рабочем месте.
// set the values
of the dynamic text fields on the stage
first_name = curr_record.first_name;
last_name = curr_record.last_name;
address = curr_record.address;
city = curr_record.city;
state = curr_record.state;
zip = curr_record.zip;
email = curr_record.email;
phone = curr_record.phone;
notes.text = curr_record.notes;
// set the birth date on the calendar
calendar_mc.setSelectedltem(curr_record.birth_date);
// we also have to tell the calendar what month to advance to
calendar_mc.setDisplayedMonth(curr_record.birth_date);
}
Текстовые поля устанавливаются в виде текстовых
полей ввода, поэтому динамические данные можно при
необходимости отображать и изменять. Так как они
являются текстовыми полями ввода, в
противопоставление динамическому тексту,
пользователь сможет изменять контактную информацию и
обновлять запись. Текстовому полю
notes было присвоено
имя инстанса, поэтому к нему может обращаться
компонент ScrollBar.
Это несколько отличается от предыдущих версий Flash,
где единственным способом доступа к текстовому полю
было имя переменной. Присваивание имен инстансов
текстовым полям является нововведением во Flash MX и
позволяет разработчику управлять динамическим
доступом к методам и свойствам поля. Компоненту
ScrollBar нужно просто
приписать имя конечного текстового поля для
правильной работы. Как только конечное поле будет
указано, ScrollBar
будет динамически изменяться, в зависимости от того,
какое количество выходящего за пределы видимой
области содержимого находится в поле по вертикали.
Конечное текстовое поле можно указать в Property
inspector для компонента
ScrollBar.
Этот
метод getSelectedContact
вызывается каждый раз при выделении в списке
ListBox, после чего весь процесс повторяется заново.
Все это излишне, и, кроме того, нет особой пользы от
"захвата" контактной информации каждый раз при
выборе имени контакта в списке. Это имеет место
только в демонстрационных целях, и я советую вам
развить дальше эту функциональность. Попробуйте
сохранять все записи в локальном объекте общего
доступа на компьютере пользователя и вставлять
информацию оттуда. Это уменьшит нагрузку на сервер,
а также увеличит в несколько раз скорость доступа,
так как данные будут считываться локально. Здесь
необходима синхронизация локальных данных с данными
на сервере.
Добавление контактов
В
следующем параграфе о PMA мы рассмотрим
функциональность, заключающуюся в добавлении контактов в
базу данных. Кнопка add является компонентом PushButton,
который вызывает метод обработки щелчка мыши
addConfirm при нажатии
кнопки.
Создадим
метод addConfirm, который
установим в качестве обработчика щелчка. При нажатии
кнопки должно отображаться сообщение, инструктирующее
пользователя о том, как добавить новый контакт. После
этого можно либо продолжить работу, либо выбрать отмену
и вернуться в PMA.
- Начнем с
отображения фильма сообщения, установив параметр
видимости компонента MessageBox на значение 1, т.к.
по умолчанию в фильме этот параметр отключен. Также
установим размер и сообщение фильма, как показано
ниже.
function addConfirm(
{
message_mc._visible = 1;
message_mc.setSize(200, 150);
message_mc.setMessage("Please fill out the form and click
К\"save\" tc add the new contact");
- Далее
устанавливаем кнопки и их ширину в MessageBox с
помощью массива кнопок для хранения имен PushButtons
в MessageBox. Затем вызываем методы
setButtons и
setButtonWidth для
динамического добавления и установки размера кнопок.
var buttons = ["Okay",
"Cancel"];
message_mc.setButtons(buttons);
message_mc.setButtonWidth(60);
- Наконец,
определяем метод закрытия обработчика.
message_mc.setCloseHandler ("addContact");
}
Затем
здесь устанавливаются некоторые параметры (такие как
размер окна) и сообщение. Возможность динамической
настройки этих параметров очень полезна, равно как и
то, что можно использовать компонент MessageBox для
других сообщений подтверждения в любом месте
приложения. Последняя строка вышеуказанного кода
устанавливает метод закрытия обработчика MessageBox,
вызываемого каждый раз при закрытии окна. Очевидно,
нам не требуется, чтобы что-либо происходило после
нажатия кнопки cancel , поэтому нужно
соответствующим образом дополнить метод
addContact.
- При нажатии
кнопки OK нужно очистить поля формы и включить
кнопку save, чтобы пользователь мог добавить
информацию о новом контакте.
function
addContact(component, buttonlndex) {
if (buttonlndex == 0) {
first_name = "";
last_name = "";
address = "";
city = "";
state = "";
zip = "";
email = "";
phone = "";
notes.text = "";
save_mc.setEnabled(true);
}
}
Так
как кнопка OK имеет в массиве индекс 0, определяем,
была ли она нажата, и очищаем поля формы перед тем,
как сделать доступной кнопку save. Если она не была
нажата, ничего не происходит, и пользователь
возвращается в PMA.
- Теперь поля ввода
очищены, и кнопка save доступна, поэтому
пользователь может создавать новую запись. Он должен
заполнить все поля, и здесь мы используем простой
метод проверки того, что заполнены именно все поля.
function validateFields()
{
if (first_name != '' && last_name != '' && address != '' &&
Кcity != '' && state != '' && zip != '' && email != '' &&
Кphone ! ='' && notes. text !=
'' && calendar_mc.getSelectedItem()) {
return true;
}
}
Этот
метод проверяет существование данных в полях, а
также выбор даты создания контакта. Разумеется,
проверка может быть изощреннее, однако для наших
целей и такая вполне годится. Если вы хотите сделать
приложение функциональнее, смело расширяйте
возможности этого метода и создайте схему проверки,
удовлетворяющую вашим нуждам. Метод
validateFields
возвращает значение true,
если форма успешно проходит проверку.
- Теперь можно
использовать этот метод совместно с методом
saveContact, который
будет вызываться при щелчке пользователем на кнопке
save для сохранения новой контактной информации в
базе данных.
function saveContact() {
if(validateFields()) {
- Так как в нашем
случае пользователь заполнил все поля, создайте
объект нового контакта для передачи в CF.
var o = new Object();
o.first_name = first_name;
o.last_name = last_name;
o.address = address;
o.city = city;
o.state = state;
o.zip = zip;
o.email = email
o.phone = phone;
o.notes = notes.text;
o.birth_date = birth_date;
- Каждый раз при
выборе даты в календаре, мы вызываем обработчик
изменений getBirthDate,
который устанавливает переменную
birth_date. Отправьте
его в saveContact CFC
через шлюз Flash.
contacts_service.saveContact(o);
} else {
- Если пользователь
не заполнил все поля, он будет оповещен об этом с
помощью того же окна сообщения, что использовалось
нами ранее. Это делается так же, как и в функции
addConfirm.
message_mc._visible = 1;
// set the size and message of the clip
message_mc.setSize(200, 150);
message_mc.setMessage ("Please be sure to fill
out all fields.");
// set the buttons and their width in the
MessageBox
var buttons = ["Okay"];
message_mc.setButtons(buttons);
message_mc.setButtonWidth(60);
- Теперь нужно
просто сбросить метод закрытия обработчика, если он
был установлен.
message_mc.setCloseHandler(null);
}
}
- Перейдем обратно
в текстовый редактор, в котором введены функции
ColdFusion, и создадим
модуль CFC, ответственный за захват информации из
объекта и добавление ее в базу данных, который мы
только что вызывали в функции
saveContact. Введите следующий код.
<!--- save contact info
--->
<cffunction name="saveContact" access="remote">
<cfquery datasource="#request.dsn#"
name="add_contact">
insert into contacts(first_name, last_name,
address, city, state,
Кzip, email, phone, notes, birth_date)
values('#flash.first_name#', '#flash.last_name#',
К'#flash.address#', '#flash.city#', '#flash.stateft',
'#flash.zip#', '#flash.email#',
К#flash.phone#', '#flash.notes#', #createodbcdate
(flash.birth_date)#);
</cfquery>
<cfreturn 1 />
</cffunction>
Если
вы уже хорошо знакомы с CF и областями применения
переменных, то обрадуетесь, узнав, что области
применения переменных Flash существуют и в
ColdFusion MX. Доступ к данным, переданным из Flash,
можно осуществлять так:
flash.имя_переменной. Это способ доступа к
данным, переданным из Flash, а также их включения в
выражение insert.
После успешного выполнения insert, возвращаем флажок
успешного завершения во Flash. Этот флажок имеет
значение 1 и будет передан обратно методу
saveContact_Result.
- Этот метод будет
выводить сообщение об успешном окончании операции,
если вставка была успешной. Он проверяет, была ли
вставка успешной, и если это так, выводит сообщение
об успешном окончании операции. Добавьте следующий
код к уже имеющимся действиям в фильме Flash.
function
saveContact_Result(success) {
if(success) {
message_mc._visible = 1;
message_mc.setSize(200, 150);
message_mc.setMessage("The new contact
was added successfully.");
// set the buttons and their width in the MessageBox
var buttons = ["Okay"];
message_mc.setButtons(buttons);
message_mc.setButtonWidth(60);
// reset the close handler method in case it was already
// set
message_mc.setCloseHandler(null);
- После этого
вызывается начальный метод
getAllContacts, который обновит список
ListBox нашим новым контактом.
contacts_service.getAllContacts();
}
}
Обновление контактов
Мы создали
функциональность, позволяющую просматривать и добавлять
контакты в приложение, однако также нужно реализовать
возможность обновления контактной информации сразу при
ее изменении. Когда контакты выбираются в списке ListBox,
их информация отображается в фильме. У пользователя
должна быть возможность изменять информацию о контакте и
обновлять запись. Это делается нажатием кнопки update,
которая вызывает метод
updateContact.
- Для этого нужно,
чтобы функция updateContact
передала обновленную информацию о контакте в CF.
function updateContact() {
// make sure that a contact is selected
if (contacts_mc.getValue()) {
// create an object that will be passed to CF for the
//update
var o = newObject();
o.id = contacts_mc.getValue();
o.first_name = first_name;
o.last_name = last_name;
o.address = address;
o.city = city;
o.state = state;
o.zip = zip;
o.email = email;
o.phone = phone;
o.notes = notes.text;
// handle the birth date
// the birth_date variable is set with the getBirthDate
//method
o.birth_date = birth_date;
// call the updateContact service
contacts_service.updateContact(o);
}
}
Как
видите, этот метод аналогичен методу
saveContact за
исключением того, что здесь осуществляется проверка
выделения в списке ListBox, так как нам нужно
запретить выполнение метода при отсутствии выделения
контакта. Идентификатор записи контакта также
передается CF для указания того, какую запись в базе
данных необходимо обновить. Номер
id сохраняется в
объекте данных наряду с другой информацией о
контакте. Этот объект затем передается методу
updateContact нашего
CFC.
- Создаем метод CFC
updateContact, чтобы
брать параметры, переданные из Flash, обновить базу
данных и передать флажок успешного завершения
операции обратно во Flash.
<!--- save existing
contact info --->
<cffunction name="updateContact"
access="remote">
<cfquery datasource="#request.dsn#"
name="save_contact">
update contactsset
first_name="#flash.first_name#",
last_name="#flash.last_name#",
Кaddress="#flash.addressft", city="#flash.citytt",
state="#flash.state#", Кzip="#flash.zip#",
email="#flash.email#", phone="#flash.phoneft",
Кnotes="#flash.notestt",
birth_date=#createodbcdate(flash.birth_date)#
where id=#flash.id#;
</cfquery>
<cfreturn 1 />
</cffunction>
- Возвращаясь к
фильму Flash, метод
updateContact_Result продолжает работу,
выводя сообщение об успешном завершении операции с
помощью компонента MessageBox практически тем же
способом, что и в функции
saveContact_Result.
function
updateContact_Result(success) {
// if the update is sucessful do the following
if (success) {
// refresh the contact ListBox after update
contacts_service.getAllContacts();
// display message to user that the update was successful
message_mc._visible = 1;
message_mc.setSize(200, 150);
message_mc.setMessage("The contact was updated
successfully.");
// set the buttons and their width in the messagebox
var buttons = ["Okay"];
message_mc.setButtons(buttons);
message_mc.setButtonWidth(60);
// reset the close handler method in case it was already set
message_mc.setCloseHandler(null);
}
}
Опять-таки, метод
getAllContacts вызывается для обновления
ListBox в случае, если информация о контакте была
изменена. Теперь можно просматривать, добавлять и
обновлять информацию о контактах, но, как вы,
наверное, чувствуете, чего-то здесь не достает.
Осталось реализовать еще одну возможность, и мы
получим полноценное приложение PMA.
Удаление контактов
PMA не
было бы законченным приложением без возможности удаления
контактов из базы данных. Рассмотрим необходимый код.
Необходимо выбрать контакт из списка, прежде чем мы
сможем с ним что-либо сделать. Затем щелчком на кнопке
delete, вызываем метод
deleteConfirm.
- Прежде всего
проверяем, выбран ли контакт. Если нет, нужно
вывести сообщение, предлагающее пользователю
выделить нужную запись.
function deleteConfirm() {
if (contacts_mc.getValue()) {
message_mc._visible = 1;
message_mc.setSize(200, 150);
message_mc.setMessage ("Are you sure you want to delete
Кthe selected entry?");
var buttons = ["Okay", "Cancel"];
message_mc.setButtons(buttons);
message_mc.setButtonWidth(60);
message_mc.setCloseHandler("deleteContact");
}
}
- Если удаление
подтверждено, можно удалить контакт. Проверка
нажатия кнопки OK осуществляется, как и прежде, с
использованием ее индекса 0. Затем нужно передать
номер id в ColdFusion.
Он сохраняется в объекте и передается методу
deleteContact CFC
контактов.
function
deleteContact(component, buttonlndex) {
if (buttonlndex == 0) {
// set the object to pass to CF
var o = new Object();
o.id = contacts_mc.getValue();
contacts_service.deleteContact(o);
}
}
- Относительно CF,
необходим лишь простой запрос на удаление, который
уберет запись из базы данных. Получив от CF флажок
успешного завершения операции через шлюз Flash,
возвращаемся к методу
deleteContact_Result.
<!--- delete contact from
the database --->
<cffunction name="deleteContact"
access="remote">
<cfquery datasource="#request.dsn#" name= "delete_contact">
delete from contacts
where id=#flash.id#;
</cfquery>
<cfreturn 1 />
</cffunction>
|