у меня аналогичная ситуация. Однако, если взять пример из приложения (ball_motion_04_click for trial.fla) то след остается. при этом заметил, что в моем проекте в поле "One item in library" виден кружок, в то время как в приложенном примере такого кружка нет. Вопрос знатокам, что не так? |
Flash, ColdFusion и Remoting
Получение контактов
Когда объекты служб объявлены, можно вызывать различные методы по мере необходимости. Так как приложение было инициализировано, необходимо осуществить первый вызов 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 требует следующие четыре параметра.
- Имя инстанса 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, после чего весь процесс повторяется заново. Все это излишне, и, кроме того, нет особой пользы от "захвата" контактной информации каждый раз при выборе имени контакта в списке. Это имеет место только в демонстрационных целях, и я советую вам развить дальше эту функциональность. Попробуйте сохранять все записи в локальном объекте общего доступа на компьютере пользователя и вставлять информацию оттуда. Это уменьшит нагрузку на сервер, а также увеличит в несколько раз скорость доступа, так как данные будут считываться локально. Здесь необходима синхронизация локальных данных с данными на сервере.