12
votes

FLEUREREFEREFERFERFERATION DE FLEX () ne peut être appelé que dans un gestionnaire d'événements utilisateur - Comment puis-je contourner cela?

Je dois appeler la filerenceference.save () après la fin d'un appel de service Web terminé, mais cette méthode a une restriction: "Dans Flash Player, vous ne pouvez appeler que cette méthode avec succès en réponse à un événement utilisateur (par exemple, dans Un gestionnaire d'événements pour un clic de souris ou un événement KeyPress). Sinon, appeler cette méthode aboutit à Flash Player lancer une exception d'erreur. " (de la documentation ici )

Cette restriction est un peu vague. Cela signifie-t-il que je ne peux appeler que la méthode de filereference.save () à partir d'une fonction de gestionnaire d'événements enregistrée comme un auditeur pour certains types d'événements utilisateur? Si oui, alors exactement quels événements utilisateur sont valides? (Peut-être qu'il y a un événement qui ne sera jamais expédié par l'interaction de l'utilisateur avec ma demande et je pourrais enregistrer une fonction de gestionnaire d'événements pour ce type d'événement et rendre l'appel de sauvegarde () de cette fonction?)

Ma difficulté est-ce que je ne peux pas appeler en toute sécurité la méthode de filereference.save () jusqu'à ce que mon service Web revienne avec les données qui seront utilisées comme argument de l'appel de la méthode FileReference.Save (), donc l'événement qui déclenche la filerenceference.Save ( ) L'appel est en fait un événement supplémentaire plutôt qu'un événement utilisateur, et je suis leyery de l'envoi d'un nouveau type d'événement (faux) utilisateur afin de pouvoir déclencher l'appel à la filerenceference.Save () à moins que ce ne soit définitivement un événement utilisateur qui ne serait jamais. Être expédié à la suite d'une interaction réelle de l'utilisateur avec ma demande.

en un mot de passe ce que je fais maintenant, c'est ceci: j'ai une fonction qui est enregistrée comme gestionnaire pour un bouton clic. Dans cette fonction, j'appelle mon service Web pour récupérer des données du serveur. J'ai également une fonction de gestionnaire de résultats qui est invoquée lorsque l'appel de service Web complète, et c'est ici que je souhaite appeler la méthode de filereference.save () car c'est à ce stade que je sais que les données sont prêtes à être enregistrées pour être enregistrées. un fichier. Mais la restriction susmentionnée me bloque de le faire - je reçois une erreur: xxx

J'ai essayé beaucoup de choses à contourner cela, comme la création d'un deuxième événement de clic de souris Fonction de gestionnaire avec la filerenceference.save () Appelez-le et appelez-le après un intervalle de temps (pour donner le temps de service Web à compléter), mais je continue à courir dans la même erreur - peut-être que cette approche ne fonctionne pas depuis la deuxième fonction N'est-ce pas enregistré comme un auditeur d'événement pour le type d'événement utilisé comme argument.

Je suis nouveau pour faire flexion du développement, alors peut-être que je ne pense pas à cela de la bonne manière. Si quelqu'un peut suggérer une autre approche, je l'apprécierais vraiment. Merci d'avance pour vos commentaires ou suggestions.

- James


0 commentaires

6 Réponses :


18
votes

Adobe Est-ce une sorte de mesure de sécurité pour que les utilisateurs soient ceux qui jouent avec des fichiers plutôt que du code potentiellement nocif. Ma compréhension est qu'elles appliquent cela en permettant uniquement aux manipulateurs de (clic?) Événements provenant de composants de l'interface utilisateur pour exécuter les méthodes de filerenceference, générer ainsi vos propres événements de manière programmatique, mais je n'ai pas essayé de vérifier cela. Malheureusement, la meilleure résolution que j'ai trouvée est de réexécuter un peu l'interface utilisateur pour se conformer à cette contrainte. Dans votre situation particulière, vous pouvez en faire un processus de deux clic avec un bouton qui dit quelque chose comme "Préparer le téléchargement", ce qui modifie "Fichier de téléchargement" après la fin du service Web. Ceci est inférieur à celui du point de vue de l'utilisateur, mais je ne pense pas qu'il y ait beaucoup d'autre que cela peut être fait, à moins que vous puissiez compléter votre appel de service Web avant d'afficher le bouton qui déclenche la filerenceference.Save () Appel.


1 commentaires

Ceci est précis. Les applications flash basées sur le navigateur devraient obéir aux règles de sandbox de navigateur normales. Une autre option utiliserait Adobe Air qui sort de la bac à sable du navigateur (mais nécessite l'installation de l'utilisateur).



4
votes

Après avoir lu pour cela pour cela, quelques heures, j'ai trouvé une solution de contournement: vous pouvez utiliser des événements MouseDown et MouseUp au lieu de cliquer simplement sur CLIQUE.

Par exemple: S: bouton Mousedown = "préparer_pdf ()" MouseUp = "sauvegarde_pdf ()"

fonctionne bien pour moi!

codage heureux!

- Thomas


2 commentaires

Merci pour cela, Thomas. Je n'ai pas salué avec cette application dans un certain temps, donc je n'ai peut-être jamais la chance de tester cela, mais cela ressemble à une bonne solution et est quelque chose de bon à connaître et à garder à l'esprit.


Si préparer_pdf est asynchrone, il semble que vous soyez dans une condition de course avec Save_PDF. Que faites-vous dans save_pdf si préparer_pdf n'est pas encore terminé?



0
votes

Ceci est un commentaire sur la réponse de Thomas (je n'ai pas encore assez de XP pour commenter): le MouseDown et MouseUp La solution de contournement fonctionne bien. Juste une note que si vous apportez des modifications dans préparer_pdf () qui nécessitent des "annulations" dans sauvegard_pdf () , alors c'est une bonne idée d'appeler ce code sur le code sur le Mouseout événement également, car il pourrait y avoir un cas que l'utilisateur MouseDown est sur le bouton, mais déplace ensuite la souris du bouton.

Ceci était particulièrement pertinent pour mon cas, dans lequel nous augmentons la taille d'une filigrane sur une image lorsque l'utilisateur clique sur le bouton de téléchargement (qui déclenche le .Save () appel). Je réduit la taille du filigrane à la normale sur le MouseDown et mouseout événements.


4 commentaires

Puisque vous faites un appel de service Web, je ne vois pas comment cela fonctionne. Vous tirez hors de l'appel de WebService de Mousedown et supposez que cela soit terminé par le temps MouseUp. Et si MouseUp arrive avant l'appel de service Web complète?


@paleozogt L'appel de service Web est déclenché sur MouseUp, pas MouseDown.


Dans l'exemple de Thomas, préparer_pdf (appelé à partir de MouseDown ) est l'appel WebService, non? Ensuite, sauvegarde_pdf (appelé à partir de MouseUp ) appelle la filerenceference.save.


Il est toujours confondre la façon dont cela est écrit, si nous faisons un appel AMF RemoteObject, comment pouvons-nous faire l'appel après la sauvegarde () est initié à MouseDown ()?



2
votes

comme une solution de contournement, j'ai utilisé la classe d'interface externe. J'ai créé une fonction JavaScript avec ce code

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


3 commentaires

Veuillez faire attention si vous répondez à un fil actif ... Ce fil a 2 ans et a une réponse acceptée!


Oui mais beaucoup de gens comme moi finissent sur des threads "anciens" de Google. Alors pourquoi ne pas offrir une alternative à un autre demandeur de réponses comme moi?


D'accord. Je suis venu ici d'une recherche Google et je veux des réponses à jour, pas seulement celle que l'OP a aimé!



0
votes

J'ai eu ce même problème, j'ai choisi d'utiliser des méthodes Flash.Net. Appelez flash.net.navigatetourl (URL); à partir d'un ActionScript ou NavigateTourl (URL); de MXML.


0 commentaires

0
votes

Ce que je fais pour résoudre ce problème, c'est afficher un message d'alerte avec une fonction anonyme, donc je n'ai pas besoin de créer un bouton.

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 commentaires