web-dev-qa-db-fra.com

Ordre d'exécution des événements lorsque vous appuyez sur PrimeFaces p: commandButton

J'essaie d'exécuter une méthode de bean JSF2 et d'afficher une boîte de dialogue après l'achèvement de la méthode en cliquant sur 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>

Lorsque je clique sur le bouton de commande, la méthode d’écoute d’action bean setResultsForSelectedRow s’exécute correctement, mais elle n’affiche pas la boîte de dialogue à la fin de la méthode. Si je supprime actionlistener, la boîte de dialogue s’affiche. Je ne sais pas ce qui ne va pas.

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

31
Abhay

Cela a échoué parce que vous avez utilisé ajax="false". Cela déclenche une requête synchrone complète qui entraîne à son tour un rechargement de page complète, ce qui empêche le lancement de oncomplete (notez que tous les autres attributs liés à ajax tels que process, onstart , onsuccess, onerror et update ne sont également jamais déclenchés).

Que cela ait fonctionné lorsque vous avez supprimé actionListener est également impossible. Cela aurait dû échouer de la même manière. Peut-être avez-vous également supprimé ajax="false" _ le long sans comprendre réellement ce que vous faisiez. Enlever ajax="false" devrait en effet répondre à l'exigence souhaitée.


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

Le script ne peut être déclenché qu'après 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 demande ajax est sur le point d'être envoyée. Mais ils ne seront jamais licenciés en même temps. La séquence est la suivante:

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

Notez que la update est effectuée après actionListener, donc si vous utilisiez onclick ou onstart pour afficher la boîte de dialogue, elle peut toujours afficher l'ancien contenu au lieu du contenu mis à jour, ce qui est médiocre pour l'expérience utilisateur. Vous feriez mieux d'utiliser oncomplete à la place pour afficher le dialogue. Notez également qu'il vaut mieux utiliser action au lieu de actionListener lorsque vous souhaitez exécuter une action commerciale.

Voir également:

126
BalusC

J'adore recevoir des informations telles que celles données par BalusC ici - et il a la gentillesse de vous aider SO beaucoup de gens avec une telle BONNE information que je considère ses paroles comme un évangile, mais je n'ai pas pu utiliser cet ordre. Dans le cadre de mon projet, BalusC a donné une excellente référence générale, ce qui m'a permis de créer un signet, ce qui me permettait de faire don de ma solution pour certains problèmes de synchronisation avancés au même endroit, car elle résout le problème de l'affiche originale. 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>

La boîte de dialogue se trouve en haut du XHTML en dehors de cette forme. Elle possède une forme distincte intégrée dans la boîte de dialogue, ainsi qu’un datatable qui contient des commandes supplémentaires pour la transmission en continu du média qui doit être amorcé et prêt à être utilisé lorsque la boîte de dialogue est activée. présenté. Vous pouvez utiliser cette même technique pour télécharger des documents personnalisés qui doivent être préparés avant de les diffuser sur l’ordinateur de l’utilisateur via les boutons fileDownload de la boîte de dialogue.

Comme je le disais, ceci est un exemple plus compliqué, mais il touche tous les points forts de votre problème et du mien. Lorsque le bouton de commande est cliqué, le résultat consiste d'abord à s'assurer que le bean de support est mis à jour avec les résultats de la liste de choix, puis demande au bean de support de préparer les flux pour l'utilisateur en fonction de leurs sélections dans la liste de sélection, puis met à jour les contrôles dans dialogue dynamique avec une mise à jour, puis affichez la boîte de dialogue prête à permettre à l'utilisateur de commencer à diffuser son contenu.

L'astuce consistait à utiliser l'ordre des événements de BalusC pour le contrôle principal, puis d'ajouter le <p:ajax process="formPickList" /> bit pour s’assurer qu’il a été exécuté d’abord - car rien ne se passe correctement à moins que la pickList mette à jour le bean de sauvegarde en premier (ce qui ne m’était pas arrivé avant de l’ajouter). Donc, oui, cette commande est géniale, car vous pouvez affecter les composants précédents, en attente et actuels ainsi que les beans de sauvegarde - mais il est parfois difficile de maîtriser le moment pour les relier tous.

Bon codage!

8
FreedomRings