FileReference.save () Flex можно вызывать только в обработчике пользовательских событий. Как это обойти? - PullRequest
12 голосов
/ 21 июля 2010

Мне нужно вызвать FileReference.save () после завершения вызова веб-службы, но этот метод имеет ограничение: «В Flash Player этот метод можно успешно вызывать только в ответ на пользовательское событие (например, в обработчик события щелчка мыши или события нажатия клавиши). В противном случае вызов этого метода приводит к тому, что Flash Player выдает исключение Error. " (из документации здесь )

Это ограничение немного расплывчато. Означает ли это, что я могу вызывать метод FileReference.save () только из функции обработчика событий, которая зарегистрирована в качестве прослушивателя для определенных типов пользовательских событий? Если да, то какие именно пользовательские события являются действительными? (Возможно, есть событие, которое никогда не будет отправлено взаимодействием пользователя с моим приложением, и я мог бы зарегистрировать функцию-обработчик событий для этого типа события и сделать вызов save () из этой функции?)

Моя трудность заключается в том, что я не могу безопасно вызывать метод FileReference.save (), пока мой веб-сервис не вернется с данными, которые будут использоваться в качестве аргумента вызова метода FileReference.save (), поэтому это событие вызывает вызов FileReference.save () на самом деле является ResultEvent, а не пользовательским событием, и я опасаюсь отправлять новый (искусственный) тип пользовательского события, чтобы иметь возможность инициировать вызов FileReference.save (), если это определенно не пользовательское событие, которое никогда не будет отправлено в результате реального взаимодействия пользователя с моим приложением.

В двух словах, я сейчас делаю так: у меня есть функция, которая зарегистрирована как обработчик для нажатия кнопки. В этой функции я выполняю вызов веб-службы для получения данных с сервера. У меня также есть функция обработчика результатов, которая вызывается после завершения вызова веб-службы, и именно здесь я хочу вызвать метод FileReference.save (), поскольку именно в этот момент я знаю, что данные готовы для сохранения в файл. Но вышеупомянутое ограничение блокирует меня от этого - я получаю ошибку:

Error #2176: Certain actions, such as those that display a pop-up window, 
may only be invoked upon user interaction, for example by a mouse click 
or button press.

Я пробовал много вещей, чтобы обойти это, таких как создание второй функции обработчика события щелчка мыши с вызовом FileReference.save () внутри и вызов ее через интервал времени ожидания (чтобы дать время веб-службе завершиться), но я продолжаю сталкиваться с одной и той же ошибкой - возможно, такой подход не работает, поскольку вторая функция не зарегистрирована в качестве прослушивателя событий для типа события, используемого в качестве аргумента.

Я новичок в разработке Flex, поэтому, возможно, я просто не думаю об этом правильно. Если кто-то может предложить другой подход, я действительно ценю это. Заранее спасибо за ваши комментарии или предложения.

- Джеймс

Ответы [ 6 ]

18 голосов
/ 21 июля 2010

Adobe делает это как своего рода меру безопасности, чтобы гарантировать, что пользователи возятся с файлами, а не с потенциально вредоносным кодом. Насколько я понимаю, они применяют это, только позволяя обработчикам событий (click?), Которые происходят из компонентов пользовательского интерфейса, выполнять методы FileReference, поэтому генерация ваших собственных событий программно не будет работать, хотя я не пытался это проверить. К сожалению, лучшее решение, которое я нашел, - немного переработать пользовательский интерфейс, чтобы соответствовать этому ограничению. В вашей конкретной ситуации вы можете сделать это в два клика с помощью кнопки с надписью «Подготовить загрузку», которая изменится на «Загрузить файл» после завершения веб-службы. Это менее чем идеально с точки зрения пользователя, но я не думаю, что можно сделать что-то еще, если вы не сможете каким-либо образом завершить вызов веб-службы до отображения кнопки, которая вызывает вызов FileReference.save ().

4 голосов
/ 19 декабря 2010

После долгих попыток я нашел обходной путь: вы можете использовать события mouseDown и mouseUp вместо простого щелчка.

Например: s: Button mouseDown = "prepare_PDF ()"mouseUp = "save_PDF ()"

У меня отлично работает!

Удачного кодирования!

- Томас

2 голосов
/ 12 ноября 2012

В качестве обходного пути я использовал класс ExternalInterface. Я создал функцию javascript с этим кодом

function downloadFile (url) {
            window.open(url);
        }

В AS3 я звоню

var url = 'www.example.com/downloadfile.php?file_id=xxx';
ExternalInterface.call('downloadAttachmentFile', url);

Итак, с этим я передаю обработку файлов в JS / HTML.

0 голосов
/ 19 декабря 2016

Чтобы решить эту проблему, я должен показать предупреждение с анонимной функцией, поэтому мне не нужно создавать кнопку.

Alert.show("Do you wish to download the file?", "Confirm", Alert.OK | Alert.CANCEL, this, function (eventObj:CloseEvent):void {
                                                                                                    if (eventObj.detail == Alert.OK) {
                                                                                                        fileReference.save(zipOut.byteArray, dateFormater_titulo.format(new Date ()) + ".zip");
                                                                                                    }//if
                                                                                                 }/*function*/, null, Alert.OK);
0 голосов
/ 15 июня 2013

У меня была такая же проблема, я решил использовать методы flash.net.Вызовите flash.net.navigateToURL(url); из скрипта действий или navigateToURL(url); из mxml.

0 голосов
/ 09 февраля 2011

Это комментарий к ответу Томаса (у меня пока недостаточно XP, чтобы комментировать): Обходное решение mousedown и mouseup прекрасно работает.Просто обратите внимание, что если вы вносите какие-либо изменения в prepare_PDF(), которые нуждаются в «отмене» в save_PDF(), то хорошей идеей будет также вызвать этот код для события mouseout, так как может быть случай, когда пользовательmousedown на кнопке, но затем отводит мышь от кнопки.

Это было особенно актуально для моего случая, в котором мы увеличиваем размер водяного знака на изображении, когда пользователь нажимает кнопку загрузки (чтобызапускает вызов .save()).Я уменьшил размер водяного знака до нормального значения для событий mousedown и mouseout.

...