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

Я пытаюсь выполнить метод bean JSF2 и показать диалоговое окно после завершения метода по нажатию 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 одновременно?

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
  • action Выполнен метод поддержки JSF
  • JSF готовит ответ Ajax на основе update и текущее дерево компонентов JSF
  • JSF отправляет ответ ajax с сервера клиенту
  • JavaScript получает ответ Ajax
    • если статус ответа HTTP равен 200, onsuccess JavaScript код выполняется
    • иначе, если статус ответа HTTP равен 500, onerror JavaScript код выполняется
  • JavaScript выполняет update основанный на ответе ajax и текущем дереве HTML DOM
  • oncomplete JavaScript код выполняется

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

Смотрите также:

Мне просто нравится получать информацию, которую 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 вне этой формы, и у него есть собственная форма, встроенная в диалог вместе с таблицей данных, которая содержит дополнительные команды для потоковой передачи мультимедиа, которые должны быть заполнены и готовы к работе, когда диалог представил. Вы можете использовать эту же технику для таких вещей, как загрузка настроенных документов, которые необходимо подготовить, прежде чем они будут переданы на компьютер пользователя с помощью кнопок fileDownload в диалоговом окне.

Как я уже сказал, это более сложный пример, но он затрагивает все основные моменты вашей проблемы и моей. Когда нажимается командная кнопка, в результате сначала необходимо убедиться, что базовый компонент обновлен с использованием результатов pickList, а затем сказать базовому компоненту подготовить потоки для пользователя на основе их выбора в списке выбора, а затем обновить элементы управления в. динамический диалог с обновлением, затем покажите диалоговое окно, готовое для пользователя, чтобы начать потоковую передачу своего контента.

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

Удачного кодирования!

Другие вопросы по тегам