Orden de ejecución de los eventos al pulsar PrimeFaces p: commandButton


Estoy tratando de ejecutar un método JSF2 bean y mostrar un cuadro de diálogo después de completar el método al hacer clic en 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>

Cuando hago clic en el botón comando, el método bean action listener setResultsForSelectedRow se ejecuta correctamente, pero no muestra el cuadro de diálogo cuando se completa el método. Si elimino actionlistener, muestra el cuadro de diálogo. No sé qué va mal.

¿Cuál es el orden de ejecución de los eventos? Es posible ejecutar actionlistener y oncomplete simultáneamente?

Author: BalusC, 2013-11-22

2 answers

Falló porque usaste ajax="false". Esto dispara una solicitud síncrona completa que a su vez causa una recarga de página completa, causando que el oncomplete nunca se dispare (tenga en cuenta que todos los demás atributos relacionados con ajax como process, onstart, onsuccess, onerror y update tampoco se disparan).

Que funcionó cuando eliminaste actionListener también es imposible. Debería haber fallado de la misma manera. Tal vez también eliminó ajax="false" a lo largo de él sin comprender realmente lo que estaba haciendo. La eliminación de ajax="false" debería de hecho lograr el requisito deseado.


También es posible ejecutar actionlistener y oncomplete simultáneamente?

No. El script solo se puede disparar antes de o después de el oyente de acciones. Puede usar onclick para activar el script en el momento del clic. Puede usar onstart para disparar el script en el momento en que la solicitud ajax está a punto de ser enviada. Pero nunca serán despedidos exactamente simultáneamente. La secuencia es como sigue:

  • Botón de clics del usuario en el cliente
  • onclick El código JavaScript se ejecuta
  • JavaScript prepara la solicitud ajax basada en process y el árbol DOM HTML actual
  • onstart El código JavaScript se ejecuta
  • JavaScript envía una solicitud ajax del cliente al servidor
  • JSF recupera solicitud ajax
  • JSF procesa el ciclo de vida de la solicitud en el árbol de componentes JSF basado en process
  • actionListener El método del frijol de respaldo de JSF es ejecutado
  • action Se ejecuta el método JSF backing bean
  • JSF prepara la respuesta ajax basada en update y el árbol de componentes actual de JSF
  • JSF envía una respuesta ajax del servidor al cliente
  • JavaScript recupera la respuesta ajax
    • si el estado de la respuesta HTTP es 200, onsuccess se ejecuta el código JavaScript
    • de lo contrario, si el estado de la respuesta HTTP es 500, onerror se ejecuta el código JavaScript
  • JavaScript realiza update basado en la respuesta ajax y árbol DOM HTML actual
  • oncomplete El código JavaScript se ejecuta

Tenga en cuenta que el {[6] } se realiza después actionListener, por lo tanto, si estaba utilizando onclick o onstart para mostrar el cuadro de diálogo, puede que todavía muestre contenido antiguo en lugar de contenido actualizado, lo cual es pobre para la experiencia del usuario. Entonces sería mejor usar oncomplete en lugar de mostrar el diálogo. También tenga en cuenta que es mejor usar action en lugar de actionListener cuando tenga la intención de ejecutar una acción de negocio.

Véase también:

 115
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:25:45

Me encanta obtener información como BalusC da aquí - y él es lo suficientemente amable para ayudar a tantas personas con tan BUENA información que considero sus palabras como evangelio, pero no fui capaz de usar ese orden de eventos para resolver este mismo tipo de problema de tiempo en mi proyecto. Desde BalusC puso una gran referencia general aquí que incluso he marcado, pensé que iba a donar mi solución para algunos problemas de tiempo avanzado en el mismo lugar, ya que resuelve los problemas de tiempo del cartel original, así. Espero que este código ayude a alguien:

        <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>

El diálogo está en la parte superior del XHTML fuera de este formulario y tiene un formulario propio incrustado en el diálogo junto con una datatable que contiene comandos adicionales para transmitir los medios que todos necesitan ser cebados y listos para funcionar cuando se presenta el diálogo. Puede usar esta misma técnica para hacer cosas como descargar documentos personalizados que deben prepararse antes de que se transmitan al ordenador del usuario a través de los botones FileDownload en el cuadro de diálogo.

Como he dicho, este es un ejemplo más complicado, pero golpea todos los puntos altos de su problema y el mío. Cuando se hace clic en el botón de comando, el resultado es asegurar primero que el frijol de respaldo se actualice con los resultados de la lista de selección, luego decirle al frijol de respaldo que prepare transmisiones para el usuario en función de sus selecciones en la lista de selección, luego actualizar los controles en el diálogo dinámico con una actualización, luego mostrar el cuadro de diálogo listo para que el usuario inicie la transmisión su contenido.

El truco era usar el orden de eventos de BalusC para el botón de comando principal y luego agregar el bit <p:ajax process="formPickList" /> para asegurarse de que se ejecutara primero, porque nada sucede correctamente a menos que la lista de selección actualice el bean de respaldo primero (algo que no estaba sucediendo para mí antes de agregarlo). Por lo tanto, sí, ese botón de comando se mueve porque puede afectar los componentes anteriores, pendientes y actuales, así como los frijoles de respaldo, pero el momento para interrelacionarlos todos no es fácil para tener un control a veces.

Feliz codificación!

 7
Author: FreedomRings,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-31 04:19:21