f: слушатель ajax выполняется после рендера? - PullRequest
3 голосов
/ 21 декабря 2011

Рассмотрим следующий jsf:

<h:panelGroup id="current" rendered="#{taskManager.currentTask != null}">
    <table>
        <tr>
            <td><h:outputText value="#{taskManager.currentTask.title}" /></td>
            <td>
                <h:form>
                    <rich:calendar id="start"
                        popup="true"
                        datePattern="yyyy-MM-dd HH:mm:ss"
                        showApplyButton="true" cellWidth="24px"
                        cellHeight="22px" style="width:200px"
                        enableManualInput="true"
                        value="#{taskManager.currentStart}">
                    </rich:calendar>

                    <h:commandButton value="Update">
                        <f:ajax execute="@form" render=":current" listener="#{taskManager.changeStart}"/>
                    </h:commandButton>

                    <h:commandButton value="Stop">
                        <f:ajax render=":current" listener="#{taskManager.stopCurrent}"/>
                    </h:commandButton>
                </h:form>
            </td>
        </tr>
        <tr>
            <td></td>
            <td>
                <h:form>
                    <rich:calendar id="stop"
                        popup="true"
                        datePattern="yyyy-MM-dd HH:mm:ss"
                        showApplyButton="true" cellWidth="24px"
                        cellHeight="22px" style="width:200px"
                        enableManualInput="true"
                        value="#{taskManager.currentStop}">
                    </rich:calendar>

                    <h:commandButton value="Stop At">
                        <f:ajax execute="@form" render=":current" listener="#{taskManager.stopCurrentAtSpecified}"/>
                    </h:commandButton>
                </h:form>
            </td>
        </tr>
    </table>
</h:panelGroup>

Как я понял из документации, "слушатель" в теге f: ajax должен быть выполнен перед повторным представлением ": current".Это основано на:

  • docs.oracle.com / javaee / 6 / tutorial / doc / gkace.html: метод processAjaxBehavior слушателя вызывается один раз на этапе Invoke Application жизненного цикла
  • javaserverfaces.java.net / nonav / docs / 2.0 / pdldocs / facelets /: идентификаторы компонентов, которые будут участвовать в части «рендеринга» жизненного цикла обработки запросов
  • www.ibm.com / developerworks/ library / j-jsf2 /: render действительно после вызова ...

Метод "# {taskManager.stopCurrentAtSpecified}" остановит задачу в указанное время и установит ее в "null", это означает, что при повторной визуализации оценка "# {taskManager.currentTask! = null}" больше не верна, поэтому панель сетки должна исчезнуть.Это не вариант.Задача действительно остановлена, но повторно отображенное представление все еще показывает старую задачу.Обновление всей страницы отобразит его правильно.

Кроме того, я поиграл с "# {taskManager.changeStart}", он обновил бы "# {taskManager.currentStop}" до очень большой даты, поэтомувы бы заподозрили, что если слушатель был выполнен и после этого выполнено рендеринг, календарь будет отображать эту большую дату, но это не так.

Я нашел кого-то с похожей проблемой, но его вопрос остался без ответа: f: ajax со слушателем и рендер

Я использую Mojarra 2.1.2

1 Ответ

1 голос
/ 21 декабря 2011

Можете ли вы попытаться добавить еще одну группу панелей, которая всегда видна, и перерисовать ее?Что-то вроде

<h:panelGroup id="current">
  <h:panelGroup rendered="#{taskManager.currentTask != null}">
    ...
  </h:panelGroup>
</h:panelGroup>

Частичные обновления заменяют содержимое элемента с указанным идентификатором.Я подозреваю, что это может быть проблематично, когда обновленный элемент не отображается.Я ожидаю, что он будет пропущен на этапе рендеринга, и, как следствие, обновление не будет создано.

Используйте ui: фрагмент или ui: компонент вместо вложенного h: panelGroup, если вы хотите избежать дополнительного пролета.

...