Ordre d'exécution des événements en appuyant sur PrimeFaces p: commandButton

j'essaie d'exécuter une méthode JSF2 bean et de montrer une boîte de dialogue après l'achèvement de la méthode sur le clic de PrimeFaces <p:commandButton> .

<p:commandButton id="viewButton" value="View"
    actionlistener="#{userBean.setResultsForSelectedRow}" ajax="false"
    update=":selectedRowValues"
    oncomplete="PF('selectedRowValuesDlg').show()">
</p:commandButton>
<p:dialog id="selectedRowValues" widgetVar="selectedRowValuesDlg" dynamic="true">
    <h:outputText value="#{userBean.selectedGroupName}" />
</p:dialog>

quand je clique sur le bouton de commande, la méthode setResultsForSelectedRow s'exécute correctement, mais elle n'affiche pas la boîte de dialogue lorsque la méthode est terminée. Si je supprime actionlistener , la boîte de dialogue s'affiche. Je ne sais pas ce qui ne va pas.

Qu'est-ce que le l'ordre d'exécution des événements? Est-il possible d'exécuter simultanément actionlistener et oncomplete ?

29
demandé sur BalusC 2013-11-22 17:57:43

2 réponses

il a échoué parce que vous avez utilisé ajax="false" . Cela déclenche une requête synchrone complète qui à son tour provoque un rechargement de page, provoquant le oncomplete à ne jamais être tiré (notez que tous les autres attributs liés à ajax comme process , onstart , onsuccess , onerror et update ne sont jamais tirés).

Qu'il a fonctionné quand vous avez enlevé actionListener est également impossible. Il n'a pas la même façon. Peut-être avez-vous aussi supprimé ajax="false" le long de lui, sans réellement comprendre ce que vous faisiez. La suppression de ajax="false" devrait effectivement permettre d'atteindre l'objectif recherché.


est-il également possible d'exécuter actionlistener et oncomplete simultanément?

Pas de. Le script ne peut être tiré que avant ou après l'auditeur d'action. Vous pouvez utiliser onclick pour lancer le script au moment du clic. Vous pouvez utiliser onstart pour lancer le script au moment où la requête ajax est sur le point d'être envoyée. Mais ils ne seront jamais tirés en même temps. La séquence est la suivante:

  • bouton clics de l'utilisateur dans le client
  • onclick le code JavaScript est exécuté
  • JavaScript prépare une requête ajax basée sur process et l'arborescence HTML actuelle
  • onstart le code JavaScript est exécuté
  • JavaScript envoie la requête ajax du client au serveur
  • JSF récupère requête ajax
  • JSF traite le cycle de vie des requêtes sur l'arbre des composants JSF basé sur process
  • actionListener la méthode JSF backbound bean est exécutée
  • action la méthode JSF backbound bean est exécutée
  • JSF prépare ajax réponse basée sur la update et actuelles JSF composant de l'arbre
  • JSF, ajax envoie la réponse du serveur au client
  • le JavaScript récupère la réponse ajax
    • si L'état de la réponse HTTP est 200, onsuccess le code JavaScript est exécuté
    • sinon si L'état de la réponse HTTP est 500, onerror le code JavaScript est exécuté
  • JavaScript exécute update basé sur la réponse ajax et L'arbre DOM HTML actuel
  • oncomplete le code JavaScript est exécuté

notez que le update est exécuté après actionListener , donc si vous utilisiez onclick ou onstart pour afficher la boîte de dialogue, alors il peut toujours afficher du contenu ancien au lieu du contenu mis à jour, ce qui est mauvais pour l'expérience de l'utilisateur. Vous feriez alors mieux d'utiliser oncomplete à la place de montrer dialogue. Notez également que vous feriez mieux d'utiliser action au lieu de actionListener lorsque vous avez l'intention d'exécuter une action commerciale.

voir aussi:

115
répondu BalusC 2017-05-23 12:25:45

j'aime juste obtenir des informations comme BalusC donne ici - et il est assez aimable pour aider tant de gens avec une telle bonne information que je considère ses mots comme l'Évangile, mais je n'ai pas été en mesure d'utiliser cet ordre d'événements pour résoudre ce même genre de problème de calendrier dans mon projet. Puisque BalusC a mis une grande référence générale ici que j'ai même signalisé, j'ai pensé que je donnerais ma solution pour certains problèmes de timing avancés dans le même endroit car il ne résout les problèmes de timing de l'affiche originale comme bien. J'espère que ce code aidera quelqu'un:

        <p:pickList id="formPickList" 
                    value="#{mediaDetail.availableMedia}" 
                    converter="MediaPicklistConverter" 
                    widgetVar="formsPicklistWidget" 
                    var="mediaFiles" 
                    itemLabel="#{mediaFiles.mediaTitle}" 
                    itemValue="#{mediaFiles}" >
            <f:facet name="sourceCaption">Available Media</f:facet>
            <f:facet name="targetCaption">Chosen Media</f:facet>
        </p:pickList>

        <p:commandButton id="viewStream_btn" 
                         value="Stream chosen media" 
                         icon="fa fa-download"
                         ajax="true"
                         action="#{mediaDetail.prepareStreams}"                                              
                         update=":streamDialogPanel"
                         oncomplete="PF('streamingDialog').show()"
                         styleClass="ui-priority-primary"
                         style="margin-top:5px" >
            <p:ajax process="formPickList"  />
        </p:commandButton>

le dialogue est au sommet du XHTML en dehors de cette forme et il a une forme de son propre intégré dans le dialogue avec un datatable qui contient des commandes supplémentaires pour la diffusion en continu des médias qui devaient tous être préparés et prêts à aller lorsque le dialogue est présenté. Vous pouvez utiliser cette même technique pour faire des choses comme télécharger des documents personnalisés qui doivent être préparés avant qu'ils soient transmis à l'ordinateur de l'utilisateur via les boutons fileDownload dans la boîte de dialogue.

Comme je l'ai dit, c'est un exemple plus compliqué, mais il touche tous les points forts de votre problème et le mien. Lorsque le bouton de commande est cliqué, le résultat est d'abord de s'assurer que le "backing bean" est mis à jour avec les résultats de la liste de sélection, puis de dire au "backing bean" de préparer les flux pour l'utilisateur en fonction de leurs sélections dans la liste de sélection, puis de mettre à jour les contrôles dans le dialogue dynamique avec une mise à jour, puis de montrer le boîte de dialogue prête pour que l'utilisateur commence à diffuser son contenu.

le truc était d'utiliser L'ordre des événements de BalusC pour le bouton de commande principal et ensuite d'ajouter le bit <p:ajax process="formPickList" /> pour s'assurer qu'il a été exécuté en premier - parce que rien ne se passe correctement à moins que la liste de sélection n'ait mis à jour le bean de soutien en premier (quelque chose qui ne se passait pas pour moi avant que je l'ai ajouté). Donc, oui, ce bouton de commande est génial parce que vous pouvez affecter les composants précédents, en attente et actuels ainsi que la sauvegarde des haricots, mais le moment d'être en interrelation tous d'entre eux n'est pas facile d'obtenir une poignée sur parfois.

bon codage!

7
répondu FreedomRings 2015-07-31 04:19:21