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 теперь работает с компонентами
Пробную версию 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-приложений можно использовать простой текстовый редактор, совместимый со многими операционными системами. Просто не забудьте сохранить ваши файлы с расширением
Написание кода CF не сложнее создания HTML-документа, и вы убедитесь в этом, как только изучите основные моменты работы с CF. В следующем примере показано несколько тегов CF и их синтаксис (в приложениях в конце лекции все будет рассмотрено подробнее). Изучив теги и их атрибуты, можно перейти к разработке сложных веб-приложений. Для начинающих проведем краткое рассмотрение основных тегов CF и объясним их назначение. Так как нам не хватит времени, чтобы рассказать обо всех тегах, начнем с наиболее важных, но в своем дальнейшем обучении вы можете отталкиваться от знаний, которые получите сейчас. На прилавках магазинов есть много хороших книг по CF, и я рекомендовал бы вам купить пару таких книг, если вы заинтересованы в продвижении в сфере программирования в CF.
Сначала мы рассмотрим настройку выходных переменных на странице. Переменные являются неотъемлемой частью программирования и могут быть использованы для хранения чисел, строк, массивов и структур. Чтобы установить переменную в ColdFusion, используется тег <cfset>.
<cfset variables.subject = "Flash Remoting">
Мы создали переменную с именем subject, содержащую значение "<cfoutput>. С помощью этих тегов происходит интерпретация всего, что находится между знаками #, в качестве переменных.
<cfoutput>#variables.subject#</cfoutput>
Результатом этой строки будет значение переменной subject, которое выведется на странице. CF поддерживает множество типов переменных. Вот некоторые из них.
Очень полезно отделять переменные по контексту, так как это ускорит работу приложений и облегчит процесс отладки. Если контекст не предоставляется, CF должен будет просматривать все доступные контексты, чтобы убедиться в существовании переменной. Также при отладке приложений, полезно знать, что переменная идет из формы или URL, вместо того, чтобы искать переменную в шаблоне.
Рассмотрим простой шаблон, демонстрирующий настройку и вывод переменной на страницу. Можно создать файл в редакторе обычного текста, однако не забудьте сохранить его в файле с расширением welcome..
<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 <!- комментарий ->. Их можно использовать и в шаблонах 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.
Мы еще раз вкратце рассмотрим упражнение "Message of the Day", проделанное в лекцию 16, однако на этот раз оно будет преобразовано в формат ColdFusion. Большинство аспектов Flash останутся теми же, за исключением того, что ссылка на update.php сменится на update.. Из этого следует, что метод 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.. Рассмотрим необходимый код 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 MX шагнул далеко вперед в предоставлении средств для разработчиков Flash. Интеграция Flash с серверами приложений стала еще теснее. Macromedia разработал новую интересную возможность для интеграции: удаленный сервис
Служба
Например, нужно построить схему аутентификации, которую можно использовать в различных ситуациях. Все, что надо сделать, это построить необходимые компоненты внешнего интерфейса, а также саму систему, которая проверяет базу данных для подтверждения данного пользователя. Эти компоненты можно повторно использовать в будущих приложениях, не создавая их вновь "с чистого листа".
Связь между Flash и сервером осуществляется через шлюз Flash gateway - компонент серверной части

Передача данных осуществляется с использованием нового набора классов ActionScript, устанавливаемых вместе с
NetServices - это абстракция NetConnection, предоставляющая средства коммуникации со шлюзом Flash gateway.NetConnection создает двойное соединение между Flash и удаленными службами.NetDebug является методом отладки приложений Flash и работает совместно с NetConnect Debugger.RecordSet поддерживает объекты набора записей, возвращаемые с сервера приложений и предоставляет различные методы доступа и управления данными наборов записей.DataGlue предоставляет возможность присваивания объектов наборов записей компонентам Flash UI, таким как компонент ListBox.Эти классы содержат много способов доступа и управления данными. На следующем рисунке показаны доступные методы для каждого из этих классов.

За более детальной информацией по методам классов
В следующем приложении используются компоненты
Это приложение создается для реализации примера, отражающего интеграцию Flash/CF. Оно называется PMA (Personal
Для использования этой базы данных необходим компьютер с установленным приложением Microsoft Access.
Для построения полнофункционального приложения необходимо обеспечить пользователей возможностью добавлять новые контакты, а также обновлять и удалять имеющиеся записи контактов. Flash будет выступать в роли пользовательского интерфейса, отображающего контактную информацию и позволяющего пользователю взаимодействовать с интерфейсом. Взаимодействие можно осуществлять, выбирая формы контакта из списка ListBox или щелчком на
Ключом к созданию динамического веб-приложения является уверенность в том, что все данные структурированы. Посмотрите на базу данных в файле pma.mdb, который поставляется вместе с исходными файлами, и откройте таблицу Contacts. Эта таблица содержит контактную информацию: имя, фамилия, адрес, адрес электронной почты и т.д. Ниже приведена структура данных для таблицы контактов.

id послужит главным ключом для каждой записи контакта и будет активно использоваться при передаче информации между Flash и ColdFusion. Поле id будет полезным при обновлении контактов или их удалении.

<cfset request.dsn = "pma">
Можно изменить имя папки, если это понадобится, однако, в этом случае, не забудьте обновить шаблон Application. для отражения изменения имени папки. Этот шаблон устанавливает ориентированную на запрос переменную с именем request.dsn, доступ к которой осуществляется через CFC. Эта переменная устанавливается в Application. как глобальная, ее можно изменить за один раз, не обновляя остального кода в приложении. Все запросы в приложении ссылаются на эту переменную, которая указывает на наш файл базы данных pma.mdb.
Если вы хотите просто запустить имеющиеся на компакт-диске файлы, а не создавать их с "чистого листа", не забудьте разархивировать файлы, содержащиеся в pma.zip в подкаталог вашего корневого каталога. Чтобы PMA запустилось с первого раза, файлы должны быть расположены в директории с именем pma прямо под вашим корневым расположением веб. Структуру директории можно изменять, однако ActionScript придется редактировать для указания нового местоположения. Обсудим вкратце этот процесс.

PMA состоит преимущественно из компонентов, которые либо поставляются с Flash MX, либо могут быть загружены с Macromedia Exchange для Flash по адресу www.macromedia.com/exchange/flash. Мы используем компоненты
Все эти компоненты предоставляют улучшенную функциональность и предотвращают надобность изобретения колеса разработчиком. Это экономит многие часы работы разработчика при создании приложений. Как только мы начнем рассматривать приложение, вы ближе ознакомитесь с этими компонентами, а также с кодом, который используется для управления ими.


Небольшое белое поле содержит окно данных (компонент MessageBox) со списком контактов. В левом нижнем углу большого белого поля располагается календарь, а в правой части элементы управления вводом и кнопки.
dynamic text состоит из набора текстовых полей для ввода, расположенных в правой части рабочего места. Они представляют собой простые текстовые поля для вода данных, с именами переменных first_name, last_name, address, city, state, zip, phone и email, соответственно. Под заголовком Notes добавьте текстовое поле для ввода с именем инстанса notes.
Закончив настройку графических элементов сайта, рассмотрим код.
#include "NetServices.as" #include "NetDebug.as" #include "DataGlue.as"
Красота этих выражений включения состоит в том, что вам не нужно знать, как выглядит код внутри них, чтобы обеспечить их работу. Нужно просто знать необходимые методы, доступные разработчику, и их предназначение. Это прекрасный пример создания приложений на базе компонентов. Разработчики могут писать необходимый код для осуществления определенных действий и передачи их дизайнерам или менее "продвинутым" разработчикам, которые смогут включить код и вызвать необходимые методы. Я отнюдь не рекламирую лентяйское отношение к программированию, а хочу показать, что код может быть распределен по компонентам, где применение отделено от интерфейса. Это значит, что внутренние действия не требуют понимания, когда доступны общие методы и возвращаются ожидаемые результаты.
Файл NetDebug.as не обязателен для корректной работы этого приложения. Он в основном используется совместно с NetConnect Debugger (Window > NetConnection Debugger) как вспомогательный файл в процессе отладки. Как только приложение готово к публикации, эта строка может быть удалена или закомментирована для уменьшения размера файла (хотя ее размер не так уж велик).
Когда необходимые классы
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);
localhost.NetServices.setDefaultGatewayUrl
("http://localhost/flashservices/gateway");
Как только PMA попадет в среду разработки, этот адрес понадобится для изменения доменного имени или IP-адреса хост-сервера. Такая мера предосторожности предотвращает возможность осуществлять вызовы служб, имеющихся на локальном сервере, внешними приложениями. Метод createGatewayConnection непосредственно создает подключение к серверу и ожидает вызова каких-либо служб. При вызове службы контактов подключение сохраняется в объекте, на который в дальнейшем будут осуществляться ссылки при вызове методов службы.
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.

Компонент 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 требует следующие четыре параметра.
contacts_mc.# )# ).При работе этот метод будет осуществлять необходимую обработку данных и заполнять поле нужными результатами.
До этого момента пользователь не принимал никакого участия в процессе. Это обстоятельство мы сейчас изменим. Существует несколько опций для пользователя, и мы расскажем о каждой из них. Также скажем, что порядок методов, перечисленных в коде 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, что может произойти при нажатии кнопки.
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); }
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, чтобы взять данные, переданные с сервера, и разместить соответствующие значения в текстовые поля ввода для отображения.
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 является компонентом addConfirm при нажатии кнопки.

Создадим метод addConfirm, который установим в качестве обработчика щелчка. При нажатии кнопки должно отображаться сообщение, инструктирующее пользователя о том, как добавить новый контакт. После этого можно либо продолжить работу, либо выбрать отмену и вернуться в PMA.
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");
setButtons и setButtonWidth для динамического добавления и установки размера кнопок.var buttons = ["Okay", "Cancel"]; message_mc.setButtons(buttons); message_mc.setButtonWidth(60);
message_mc.setCloseHandler ("addContact");
}
Затем здесь устанавливаются некоторые параметры (такие как размер окна) и сообщение. Возможность динамической настройки этих параметров очень полезна, равно как и то, что можно использовать компонент MessageBox для других сообщений подтверждения в любом месте приложения. Последняя строка вышеуказанного кода устанавливает метод закрытия обработчика MessageBox, вызываемого каждый раз при закрытии окна. Очевидно, нам не требуется, чтобы что-либо происходило после нажатия кнопки cancel , поэтому нужно соответствующим образом дополнить метод addContact.
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.
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()) {
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.
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.
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>
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");
}
}
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);
}
}
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>
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 теперь работает с компонентами
Пробную версию 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-приложений можно использовать простой текстовый редактор, совместимый со многими операционными системами. Просто не забудьте сохранить ваши файлы с расширением
Написание кода CF не сложнее создания HTML-документа, и вы убедитесь в этом, как только изучите основные моменты работы с CF. В следующем примере показано несколько тегов CF и их синтаксис (в приложениях в конце лекции все будет рассмотрено подробнее). Изучив теги и их атрибуты, можно перейти к разработке сложных веб-приложений. Для начинающих проведем краткое рассмотрение основных тегов CF и объясним их назначение. Так как нам не хватит времени, чтобы рассказать обо всех тегах, начнем с наиболее важных, но в своем дальнейшем обучении вы можете отталкиваться от знаний, которые получите сейчас. На прилавках магазинов есть много хороших книг по CF, и я рекомендовал бы вам купить пару таких книг, если вы заинтересованы в продвижении в сфере программирования в CF.
Сначала мы рассмотрим настройку выходных переменных на странице. Переменные являются неотъемлемой частью программирования и могут быть использованы для хранения чисел, строк, массивов и структур. Чтобы установить переменную в ColdFusion, используется тег <cfset>.
<cfset variables.subject = "Flash Remoting">
Мы создали переменную с именем subject, содержащую значение "<cfoutput>. С помощью этих тегов происходит интерпретация всего, что находится между знаками #, в качестве переменных.
<cfoutput>#variables.subject#</cfoutput>
Результатом этой строки будет значение переменной subject, которое выведется на странице. CF поддерживает множество типов переменных. Вот некоторые из них.
Очень полезно отделять переменные по контексту, так как это ускорит работу приложений и облегчит процесс отладки. Если контекст не предоставляется, CF должен будет просматривать все доступные контексты, чтобы убедиться в существовании переменной. Также при отладке приложений, полезно знать, что переменная идет из формы или URL, вместо того, чтобы искать переменную в шаблоне.
Рассмотрим простой шаблон, демонстрирующий настройку и вывод переменной на страницу. Можно создать файл в редакторе обычного текста, однако не забудьте сохранить его в файле с расширением welcome..
<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 <!- комментарий ->. Их можно использовать и в шаблонах 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.
Мы еще раз вкратце рассмотрим упражнение "Message of the Day", проделанное в лекцию 16, однако на этот раз оно будет преобразовано в формат ColdFusion. Большинство аспектов Flash останутся теми же, за исключением того, что ссылка на update.php сменится на update.. Из этого следует, что метод 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.. Рассмотрим необходимый код 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 MX шагнул далеко вперед в предоставлении средств для разработчиков Flash. Интеграция Flash с серверами приложений стала еще теснее. Macromedia разработал новую интересную возможность для интеграции: удаленный сервис
Служба
Например, нужно построить схему аутентификации, которую можно использовать в различных ситуациях. Все, что надо сделать, это построить необходимые компоненты внешнего интерфейса, а также саму систему, которая проверяет базу данных для подтверждения данного пользователя. Эти компоненты можно повторно использовать в будущих приложениях, не создавая их вновь "с чистого листа".
Связь между Flash и сервером осуществляется через шлюз Flash gateway - компонент серверной части

Передача данных осуществляется с использованием нового набора классов ActionScript, устанавливаемых вместе с
NetServices - это абстракция NetConnection, предоставляющая средства коммуникации со шлюзом Flash gateway.NetConnection создает двойное соединение между Flash и удаленными службами.NetDebug является методом отладки приложений Flash и работает совместно с NetConnect Debugger.RecordSet поддерживает объекты набора записей, возвращаемые с сервера приложений и предоставляет различные методы доступа и управления данными наборов записей.DataGlue предоставляет возможность присваивания объектов наборов записей компонентам Flash UI, таким как компонент ListBox.Эти классы содержат много способов доступа и управления данными. На следующем рисунке показаны доступные методы для каждого из этих классов.

За более детальной информацией по методам классов
В следующем приложении используются компоненты
Это приложение создается для реализации примера, отражающего интеграцию Flash/CF. Оно называется PMA (Personal
Для использования этой базы данных необходим компьютер с установленным приложением Microsoft Access.
Для построения полнофункционального приложения необходимо обеспечить пользователей возможностью добавлять новые контакты, а также обновлять и удалять имеющиеся записи контактов. Flash будет выступать в роли пользовательского интерфейса, отображающего контактную информацию и позволяющего пользователю взаимодействовать с интерфейсом. Взаимодействие можно осуществлять, выбирая формы контакта из списка ListBox или щелчком на
Ключом к созданию динамического веб-приложения является уверенность в том, что все данные структурированы. Посмотрите на базу данных в файле pma.mdb, который поставляется вместе с исходными файлами, и откройте таблицу Contacts. Эта таблица содержит контактную информацию: имя, фамилия, адрес, адрес электронной почты и т.д. Ниже приведена структура данных для таблицы контактов.

id послужит главным ключом для каждой записи контакта и будет активно использоваться при передаче информации между Flash и ColdFusion. Поле id будет полезным при обновлении контактов или их удалении.

<cfset request.dsn = "pma">
Можно изменить имя папки, если это понадобится, однако, в этом случае, не забудьте обновить шаблон Application. для отражения изменения имени папки. Этот шаблон устанавливает ориентированную на запрос переменную с именем request.dsn, доступ к которой осуществляется через CFC. Эта переменная устанавливается в Application. как глобальная, ее можно изменить за один раз, не обновляя остального кода в приложении. Все запросы в приложении ссылаются на эту переменную, которая указывает на наш файл базы данных pma.mdb.
Если вы хотите просто запустить имеющиеся на компакт-диске файлы, а не создавать их с "чистого листа", не забудьте разархивировать файлы, содержащиеся в pma.zip в подкаталог вашего корневого каталога. Чтобы PMA запустилось с первого раза, файлы должны быть расположены в директории с именем pma прямо под вашим корневым расположением веб. Структуру директории можно изменять, однако ActionScript придется редактировать для указания нового местоположения. Обсудим вкратце этот процесс.

PMA состоит преимущественно из компонентов, которые либо поставляются с Flash MX, либо могут быть загружены с Macromedia Exchange для Flash по адресу www.macromedia.com/exchange/flash. Мы используем компоненты
Все эти компоненты предоставляют улучшенную функциональность и предотвращают надобность изобретения колеса разработчиком. Это экономит многие часы работы разработчика при создании приложений. Как только мы начнем рассматривать приложение, вы ближе ознакомитесь с этими компонентами, а также с кодом, который используется для управления ими.


Небольшое белое поле содержит окно данных (компонент MessageBox) со списком контактов. В левом нижнем углу большого белого поля располагается календарь, а в правой части элементы управления вводом и кнопки.
dynamic text состоит из набора текстовых полей для ввода, расположенных в правой части рабочего места. Они представляют собой простые текстовые поля для вода данных, с именами переменных first_name, last_name, address, city, state, zip, phone и email, соответственно. Под заголовком Notes добавьте текстовое поле для ввода с именем инстанса notes.
Закончив настройку графических элементов сайта, рассмотрим код.
#include "NetServices.as" #include "NetDebug.as" #include "DataGlue.as"
Красота этих выражений включения состоит в том, что вам не нужно знать, как выглядит код внутри них, чтобы обеспечить их работу. Нужно просто знать необходимые методы, доступные разработчику, и их предназначение. Это прекрасный пример создания приложений на базе компонентов. Разработчики могут писать необходимый код для осуществления определенных действий и передачи их дизайнерам или менее "продвинутым" разработчикам, которые смогут включить код и вызвать необходимые методы. Я отнюдь не рекламирую лентяйское отношение к программированию, а хочу показать, что код может быть распределен по компонентам, где применение отделено от интерфейса. Это значит, что внутренние действия не требуют понимания, когда доступны общие методы и возвращаются ожидаемые результаты.
Файл NetDebug.as не обязателен для корректной работы этого приложения. Он в основном используется совместно с NetConnect Debugger (Window > NetConnection Debugger) как вспомогательный файл в процессе отладки. Как только приложение готово к публикации, эта строка может быть удалена или закомментирована для уменьшения размера файла (хотя ее размер не так уж велик).
Когда необходимые классы
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);
localhost.NetServices.setDefaultGatewayUrl
("http://localhost/flashservices/gateway");
Как только PMA попадет в среду разработки, этот адрес понадобится для изменения доменного имени или IP-адреса хост-сервера. Такая мера предосторожности предотвращает возможность осуществлять вызовы служб, имеющихся на локальном сервере, внешними приложениями. Метод createGatewayConnection непосредственно создает подключение к серверу и ожидает вызова каких-либо служб. При вызове службы контактов подключение сохраняется в объекте, на который в дальнейшем будут осуществляться ссылки при вызове методов службы.
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.

Компонент 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 требует следующие четыре параметра.
contacts_mc.# )# ).При работе этот метод будет осуществлять необходимую обработку данных и заполнять поле нужными результатами.
До этого момента пользователь не принимал никакого участия в процессе. Это обстоятельство мы сейчас изменим. Существует несколько опций для пользователя, и мы расскажем о каждой из них. Также скажем, что порядок методов, перечисленных в коде 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, что может произойти при нажатии кнопки.
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); }
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, чтобы взять данные, переданные с сервера, и разместить соответствующие значения в текстовые поля ввода для отображения.
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 является компонентом addConfirm при нажатии кнопки.

Создадим метод addConfirm, который установим в качестве обработчика щелчка. При нажатии кнопки должно отображаться сообщение, инструктирующее пользователя о том, как добавить новый контакт. После этого можно либо продолжить работу, либо выбрать отмену и вернуться в PMA.
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");
setButtons и setButtonWidth для динамического добавления и установки размера кнопок.var buttons = ["Okay", "Cancel"]; message_mc.setButtons(buttons); message_mc.setButtonWidth(60);
message_mc.setCloseHandler ("addContact");
}
Затем здесь устанавливаются некоторые параметры (такие как размер окна) и сообщение. Возможность динамической настройки этих параметров очень полезна, равно как и то, что можно использовать компонент MessageBox для других сообщений подтверждения в любом месте приложения. Последняя строка вышеуказанного кода устанавливает метод закрытия обработчика MessageBox, вызываемого каждый раз при закрытии окна. Очевидно, нам не требуется, чтобы что-либо происходило после нажатия кнопки cancel , поэтому нужно соответствующим образом дополнить метод addContact.
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.
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()) {
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.
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.
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>
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");
}
}
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);
}
}
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>
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.