Как открыть синхронный диалог в Flex? Мне нужно вызвать функцию из внешнего интерфейса (JavaScript), которая откроет простой диалог в приложении Flex и вернет значение в соответствии с кнопкой, которую нажал пользователь (OK / Отмена).
Таким образом, это должно быть синхронным вызовом диалога, то есть вызов ожидает, пока пользователь не закроет диалог, подобный этому.
//This function is called by JavaScript
function onApplicationUnload():Boolean
{
var result:Boolean;
result = showDialogAndWaitForResult();
return result
}
Кто-нибудь знает, как я могу это сделать? Я мог бы написать цикл, который ждет, пока диалог не установит флаг, а затем считывает результат, чтобы вернуть его, но должно быть что-то более элегантное и многоразовое для ожидания завершения других асинхронных вызовов.
Обновлено: К сожалению, обратный вызов не работает, поскольку функция JavaScript, вызывающая onApplicationUnload (), сама должна возвращать значение (аналогично функции onApplicationUnload () в Flex). Эта функция JavaScript имеет фиксированную подпись, поскольку она вызывается фреймворком, и я не могу ее изменить. Или другими словами: вызов из JavaScript в Flex также должен быть синхронным.





Flex не работает синхронно, так как это однопоточное приложение, и ему требуется, чтобы ваш код возвращал выполнение обратно в «ядро» для обработки пользовательского ввода и т. д.
Способ сделать это - сделать поведение вашего диалога асинхронным:
function onApplicationUnload():void
{
showDialog(resultMethod);
}
function resultMethod(result:Boolean):void
{
ExternalInterface.call("javaScriptCallback", [result]);
}
Тогда, как говорит Хермс, у вас нет возможности использовать Flex для решения этой проблемы, и вам придется вместо этого использовать диалог JavaScript. Прости за это.
Вы не можете этого сделать в Flex. Как упоминал Дэвид, Flex является однопоточным, поэтому вы не можете иметь свой функциональный блок во время обработки диалога.
Лучше всего использовать всплывающее окно Javascript. У вас будет гораздо меньше контроля над окном, но оно должно вести себя так, как вы хотите (блокировать функцию до тех пор, пока она не будет закрыта).
Хорошо ... в конце концов, я нашел возможное решение. Но, думаю, вряд ли все будут заниматься этим всерьез :-(
Решение фокусируется на использовании цикла while для проверки результата и последующего возврата функции, вызываемой JavaScript. Однако нам нужен способ уснуть в цикле while, пока мы ждем результата. Однако вызовы JavaScript синхронны. Теперь уловка состоит в том, чтобы «засыпать» в JavaScript, который также здесь не доступен напрямую, но может быть выполнен с помощью синхронного запроса XML Http, как описано в этом блог.
Как я уже сказал, я не буду рекомендовать это только в крайнем случае. Для моей проблемы я прибегал к уродливым всплывающим окнам JavaScript.
Вы можете имитировать синхронный диалог во флексе, открыв диалоговое окно и отключив все в фоновом режиме. Вы можете увидеть это в действии, если сделаете Alert.show("Hello World"); в приложении. Фон станет серым, и пользователь не сможет щелкнуть какой-либо пользовательский интерфейс в фоновом режиме. Приложение будет «ждать», пока пользователь не нажмет кнопку ОК.
Проблема не в этом. Проблема здесь в том, что функция продолжает работать, когда она открыла диалоговое окно, и, таким образом, нет реального способа дождаться возвращаемого значения диалогового окна, которое должно быть возвращено этой функцией.
Это должно отображаться, когда страница закрыта?
Почти: он должен отображаться прямо перед закрытием страницы. И в зависимости от кода возврата вызова JavaScript (который вызывает функцию Flex, отображающую диалоговое окно), страница будет оставлена или нет.
Пусть ваш диалог вызовет другую функцию в flex для обработки результата выбора пользователя:
private function deleteFileCheck():void
{
Alert.show("Are you sure you want to delete this file?",
"Confirm Delete",
Alert.YES| Alert.NO,
this, deleteFileHandler, null, Alert.NO);
}
private function deleteFileHandler(event:CloseEvent):void
{
if (event.detail == Alert.YES)
{
...do your processing here
}
}
Пусть ваш код Flex использует событие для ожидания диалогового окна. В основном потоке зарегистрируйте обработчик событий, ожидающий закрытия диалогового окна. Нажав ОК в диалоговом окне, отправьте событие завершения диалогового окна.
С Cairngorm это примерно так:
В основном потоке:
CairngormEventDispatcher.getInstance().addEventListener(ClosingDialogCompleteEvent.DIALOG_COMPLETE, onClosingDialogComplete);
(если вы хотите избежать возврата до завершения, выполните цикл по таймеру и глобальной переменной.)
В обработчике закрытия диалога:
CairngormEventDispatcher.dispatchEvent(new ClosingDialogCompleteEvent(<parameters>));
Обработчик события:
public function onClosingDialogComplete (e: ClosingDialogCompleteEvent):void
{
param1 = e.param1;
param2 = e.param2;
// etc.
// Continue processing or set the global variable that signals the main thread to continue.
}
Чтобы это работало, необходимо определить класс ClosingDialogCompleteEvent. Частичный код класса:
package com. ... .event // You define where the event lives.
{
import com.adobe.cairngorm.control.CairngormEvent;
public class ClosingDialogCompleteEvent extends CairngormEvent
{
// Event type.
public static const DIALOG_COMPLETE:String = "dialogComplete";
public var param1:String;
public var param2:String;
public function ClosingDialogCompleteEvent(param1:String, param2:String)
{
super(DIALOG_COMPLETE);
this.param1 = param1;
this.param2 = param2;
}
}
}
Ожидание события - лучший способ синхронизации в Flex. Он также хорошо работает для диалоговых окон при запуске. В приложении, предназначенном только для гибкости, это работает особенно хорошо.
Еще нужна еще одна функция ... Это не то, что мне нужно. Мне нужно вызвать функцию и дождаться возврата результата.
Я объяснил обходной путь для создания синхронного оповещения в гибком
http://reallypseudorandom.blogspot.com/2010/05/flash-asynchronous-alert-and-pause.html
Функция JavaScript, вызвавшая onApplicationUnload (), также должна дождаться результата, чтобы его вернуть. У меня нет возможности изменить это на стороне JavaScript, так как у меня также есть функция, которая должна возвращать значение, которое передается в структуру приложения.