Порядок выполнения событий при нажатии 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 setResultsForSelectedRow
выполняется правильно, но при завершении метода он не отображает диалоговое окно. Если я удалю actionlistener
, появится диалоговое окно. Я не знаю, что происходит.
Каков порядок выполнения событий? Можно ли одновременно выполнять actionlistener
и oncomplete
?
Ответы
Ответ 1
Не удалось, потому что вы использовали ajax="false"
. Это вызывает полный синхронный запрос, который, в свою очередь, вызывает полную перезагрузку страницы, в результате чего oncomplete
никогда не запускается (обратите внимание, что все другие атрибуты, связанные с ajax, такие как process
, onstart
, onsuccess
, onerror
и update
также не запускаются).
То, что это сработало, когда вы удалили actionListener
, также невозможно. Он должен был потерпеть неудачу так же. Возможно, вы также удалили ajax="false"
вдоль него, не понимая, что вы делаете. Удаление ajax="false"
должно действительно достичь желаемого требования.
Также возможно одновременное выполнение actionlistener и oncomplete?
Нет. script может быть запущен только до или после прослушивателя действий. Вы можете использовать onclick
для запуска script в момент щелчка. Вы можете использовать onstart
для запуска script в момент отправки запроса ajax. Но они никогда не будут точно одновременно уволены. Последовательность выглядит следующим образом:
- Пользователь нажимает кнопку на клиенте
-
onclick
Выполняется код JavaScript
- JavaScript готовит запрос ajax на основе
process
и текущего дерева HTML DOM
-
onstart
Выполняется JavaScript-код
- JavaScript отправляет запрос ajax от клиента к серверу
- JSF получает запрос ajax
- JSF обрабатывает жизненный цикл запроса в дереве компонентов JSF на основе
process
-
actionListener
Выполняется метод поддержки JSF bean
-
action
Выполняется метод поддержки JSF 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
, когда вы намереваетесь выполнить бизнес-действие.
См. также:
Ответ 2
Мне просто нравится получать информацию, такую как BalusC, здесь, и он достаточно любезен, чтобы помочь ТАК много людей с такой хорошей информацией, что я считаю его слова как евангелие, но я не мог использовать этот порядок событий для решения этого же вид сроков в моем проекте. Поскольку 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 в диалоговом окне.
Как я уже сказал, это более сложный пример, но он поражает все точки вашей проблемы и мои. Когда нажата кнопка командной строки, результат сначала гарантирует, что резервная копия bean будет обновлена с результатами pickList, а затем сообщите резервной копии bean для подготовки потоков для пользователя на основе их выбора в списке выбора, затем обновите элементы управления в динамическом диалоге с обновлением, затем отобразите диалоговое окно, готовое для того, чтобы пользователь начал передавать потоковое содержимое.
Уловкой для этого было использование порядка событий BalusC для основного CommandButton, а затем добавить бит <p:ajax process="formPickList" />
, чтобы убедиться, что он был выполнен первым - потому что ничего не происходит правильно, если pickList не обновил поддержку bean сначала (что-то это не произошло для меня, прежде чем я добавил). Итак, да, этот commandButton сказывается, потому что вы можете воздействовать на предыдущие, ожидающие и текущие компоненты, а также на поддержку beans, но время, необходимое для их взаимосвязи, не всегда легко обрабатывать.
Счастливое кодирование!