Порядок выполнения событий при нажатии на PrimeFaces p: commandButton

Я пытаюсь выполнить метод jsf2 bean и показать диалоговое окно После завершения метода по щелчку 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>

когда я нажимаю на кнопку команды, метод Bean action listener setResultsForSelectedRow выполняется правильно, но не показывает диалоговое окно, когда метод завершается. Если я удалю actionlistener, он показывает диалоговое окно. Я не знаю, что происходит.

каков порядок выполнения событий? Возможно ли выполнить actionlistener и oncomplete одновременно?

2 ответов


это не удалось, потому что вы использовали ajax="false". Это запускает полный синхронный запрос, который, в свою очередь, вызывает полную перезагрузку страницы, вызывая oncomplete никогда не будет уволен (обратите внимание, что все другие атрибуты, связанные с ajax, такие как process, onstart, onsuccess, onerror и update также никогда не стрелял).

что он работал, когда вы удалены actionListener тоже нельзя. Он должен был провалиться точно так же. Возможно, вы также удалили ajax="false" по нему фактически не понимая, что вы были делающий. Удаление ajax="false" действительно должно достичь желаемого требования.


также возможно выполнить actionlistener и oncomplete одновременно?

нет. Скрипт можно только запустить до или после действие слушателя. Вы можете использовать onclick чтобы запустить скрипт в момент щелчка. Вы можете использовать onstart чтобы запустить скрипт в тот момент, когда запрос ajax будет отправленный. Но они никогда не будут выпущены одновременно. Последовательность выглядит следующим образом:

  • пользователь нажимает кнопку в клиенте
  • onclick выполняется код JavaScript
  • JavaScript готовит запрос ajax на основе process и текущее дерево HTML DOM
  • onstart выполняется код JavaScript
  • JavaScript отправляет ajax-запрос от клиента к серверу
  • JSF получает запрос ajax
  • в JSF обрабатывает жизненный цикл запроса в дереве компонентов JSF на основе process
  • actionListener выполняется метод JSF backing bean
  • action выполняется метод JSF backing bean
  • JSF готовит ответ ajax на основе update и текущее дерево компонентов JSF
  • JSF отправляет ajax-ответ от сервера клиенту
  • JavaScript получает ответ ajax
    • если состояние ответа HTTP равно 200,onsuccess код JavaScript казнен
    • else если состояние ответа HTTP равно 500,onerror выполняется код JavaScript
  • JavaScript выполняет update на основе ответа ajax и текущего дерева HTML DOM
  • oncomplete выполняется код JavaScript

отметим, что update выполняется после actionListener, так что если вы используете onclick или onstart чтобы показать диалог, то он может по-прежнему показывать старый контент вместо обновленного контента, что плохо для пользовательского опыта. Тогда вам лучше использовать oncomplete вместо этого, чтобы показать диалоговое окно. Также обратите внимание, что вам лучше использовать action вместо actionListener когда вы собираетесь выполнить бизнес-действие.

Читайте также:


Я просто люблю получать информацию, как Балуск дает здесь - и он достаточно любезен, чтобы помочь стольким людям с такой хорошей информацией, что я считаю его слова Евангелием, но я не смог использовать этот порядок событий для решения такого же вопроса времени в моем проекте. Поскольку BalusC поместил здесь отличную общую ссылку, которую я даже заложил в закладку, я подумал, что пожертвую свое решение для некоторых продвинутых проблем времени в том же месте, поскольку он решает проблемы времени оригинального плаката как что ж. Надеюсь, этот код кому-то поможет:

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

диалог находится в верхней части XHTML вне этой формы, и он имеет свою собственную форму, встроенную в диалог вместе с datatable, который содержит дополнительные команды для потоковой передачи мультимедиа, которые все должны быть загрунтованы и готовы к работе, когда диалог представлен. Этот же метод можно использовать для загрузки настраиваемых документов, которые необходимо подготовить до их передачи на компьютер пользователя через fileDownload кнопки в диалоговом окне, а также.

хитрость заключалась в том, чтобы использовать порядок событий BalusC для главной командной кнопки, а затем добавить <p:ajax process="formPickList" /> бит, чтобы убедиться, что он был выполнен первым - потому что ничего не происходит правильно, если раскрывающийся список сначала не обновил резервный компонент (что-то, что не происходило для меня, прежде чем я добавил его). Итак, да, эта commandButton rocks, потому что вы можете повлиять на предыдущие, ожидающие и текущие компоненты, а также на резервные компоненты, но время со всеми из них иногда непросто справиться.

удачи в кодировании!