Le fichier FileReference.save () de Flex ne peut être appelé que dans un gestionnaire d'événements utilisateur. Comment puis-je contourner ce problème?
J'ai besoin d'appeler FileReference.save() après un appel de service web est terminé, mais cette méthode a une restriction: "Dans Flash Player, vous pouvez uniquement appeler cette méthode avec succès, en réponse à un événement utilisateur (par exemple, dans un gestionnaire d'événement pour un clic de souris ou un événement keypress). Sinon, l'appel de cette méthode aboutit à Flash Player de lancer une Erreur d'exception." (à partir de la documentation ici)
Cette restriction est un peu vague. Ça veut dire que je ne peux appeler le FileReference.méthode save() dans une fonction de gestionnaire d'événement qui est inscrit comme auditeur pour certains types d'événements de l'utilisateur? Si oui, alors exactement ce qui les événements de l'utilisateur sont valides? (Peut-être il y a un événement qui ne sera jamais distribué par l'interaction de l'utilisateur avec ma demande et j'ai pu enregistrer une fonction de gestionnaire d'événement de ce type d'événement et de faire de la save() appel à partir de l'intérieur de cette fonction?)
Mon problème est que je ne peux pas en toute sécurité appeler le FileReference.méthode save() jusqu'à ce que mon web service renvoie les données qui seront utilisées comme argument de la FileReference.méthode save() de façon à ce que l'événement qui déclenche l'FileReference.enregistrer() l'appel est en fait un ResultEvent plutôt que d'un événement utilisateur, et je suis réticent à l'idée de l'envoi d'une nouvelle (fausse) de l'utilisateur type d'événement afin d'être en mesure de déclencher l'FileReference.save() de l'appel, sauf si c'est vraiment un événement utilisateur qui ne sera jamais distribué en tant que résultat de réelle interaction de l'utilisateur avec ma demande.
En un mot ce que je fais maintenant est ceci: j'ai une fonction qui est enregistré en tant que gestionnaire pour un clic sur un bouton. Dans cette fonction, je fais mon appel de service web pour récupérer des données à partir du serveur. J'ai aussi un résultat de la fonction du gestionnaire qui est appelé lors de l'appel de service web est terminée, et c'est ici que je veux appeler la FileReference.méthode save() puisque c'est à ce moment que je sais que les données sont prêtes à être enregistrées dans un fichier. Mais ladite restriction est me bloque de le faire -- j'obtiens une erreur:
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.
J'ai essayé beaucoup de choses pour contourner ce problème, tels que la création d'un deuxième clic de souris en fonction de gestionnaire d'événement avec la FileReference.save() appel à l'intérieur et à l'appeler après un intervalle de délai d'attente (pour donner le service web de temps à terminer), mais j'ai garder en cours d'exécution dans la même erreur, peut-être que cette approche ne fonctionne pas depuis la deuxième fonction n'est pas enregistré comme un écouteur d'événement pour l'événement du type utilisé comme argument.
Je suis nouveau développement Flex, donc je suis peut-être tout simplement pas de penser à ce sujet dans le droit chemin. Si quelqu'un peut suggérer une autre approche que je l'apprécierais vraiment. Merci d'avance pour vos commentaires ou suggestions.
--James
source d'informationauteur James Adams
Vous devez vous connecter pour publier un commentaire.
Adobe ne ce comme une sorte de mesure de sécurité pour s'assurer que les utilisateurs sont ceux de jouer avec plutôt que des fichiers potentiellement dangereux code. Ma compréhension est qu'il s'agit d'appliquer ce, en autorisant uniquement les gestionnaires de (sur?) les événements qui proviennent des composants de l'INTERFACE utilisateur pour exécuter l'FileReference de méthodes, de sorte à générer vos propres événements par programme ne fonctionnera pas, même si je n'ai pas essayé de le vérifier. Malheureusement la meilleure solution que j'ai trouvé est de re-travail de l'INTERFACE utilisateur un peu pour se conformer à cette contrainte. Dans votre situation particulière, vous pouvez faire ce en deux clic d'un bouton qui dit quelque chose comme "Préparer Télécharger", qui change de "Téléchargement de Fichiers" après le service web est complète. C'est moins que l'idéal d'un point de vue utilisateur, mais je ne pense pas qu'il y a beaucoup de chose qui peut être fait, sauf si vous pouvez en quelque sorte compléter votre appel de service web avant l'affichage du bouton qui déclenche le FileReference.save() de l'appel.
Après avoir lutté pour que de bien, une couple d'heures, j'ai trouvé une solution de contournement: vous pouvez utiliser les deux événements mouseDown ET mouseUp, au lieu de il suffit de cliquer.
Par exemple:
s:Bouton
mouseDown="prepare_PDF()"
mouseUp="save_PDF()"
Fonctionne très bien pour moi!
Bon codage!
--Thomas
Comme une solution de contournement que j'ai utilisé de la classe ExternalInterface. J'ai créé une fonction javascript avec ce code
Un en AS3 j'appelle
Donc, avec ce que j'ai le transfert de la gestion des fichiers JS/HTML.
Ceci est un commentaire sur Thomas' réponse (je n'ai pas assez d'XP pour commentaire pour le moment): Le
mousedown
etmouseup
solution fonctionne très bien. Juste une remarque si vous effectuez des modifications dansprepare_PDF()
qui ont besoin de "défaire" danssave_PDF()
ensuite ses une bonne idée d'appeler ce code sur lemouseout
événement, car il pourrait y avoir un cas où l'utilisateur mousedown sur le bouton, mais puis déplace la souris en dehors du bouton.C'était particulièrement important pour mon cas, dans lequel on augmente la taille d'un filigrane sur une image lorsque l'utilisateur clique sur le bouton de téléchargement (qui déclenche la
.save()
appel). - Je réduire la taille du filigrane en bas à la normale sur lamousedown
etmouseout
événements.J'ai eu ce même problème, j'ai choisi d'utiliser flash.net des méthodes. Appel
flash.net.navigateToURL(url);
à partir d'actionscript ounavigateToURL(url);
de mxml.Ce que je fais pour résoudre ce problème est d'afficher un message d'alerte avec une fonction anonyme donc je n'ai pas de créer un bouton.