考虑以下 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 标记中的“监听器”应该在部分 View “: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/:渲染确实是在调用之后...
方法“#{taskManager.stopCurrentAtSpecified}”将在给定时间停止任务并将其设置为“null”,这意味着在重新渲染时评估“#{taskManager.currentTask != null}”不再为真所以网格面板应该消失。不是这种情况。任务确实停止了,但是重新渲染的 View 仍然显示旧任务。刷新整个页面将正确呈现它。
此外,我还尝试了“#{taskManager.changeStart}”,它会将“#{taskManager.currentStop}”更新为一个非常大的日期,因此您会怀疑是否执行了监听器并执行了渲染,日历会反射(reflect)这个大日期,但事实并非如此。
我发现有人有类似的问题,但他的问题没有得到解答:f:ajax with listener and render
我正在使用 Mojarra 2.1.2
最佳答案
您可以尝试添加另一个始终可见的 panelGroup 并重新渲染它吗?有点像
<h:panelGroup id="current">
<h:panelGroup rendered="#{taskManager.currentTask != null}">
...
</h:panelGroup>
</h:panelGroup>
部分更新替换具有指定 id 的元素的内容。我怀疑当未呈现更新的元素本身时可能会出现问题。我希望它在渲染阶段被跳过,因此不会生成更新。
如果您想避免额外的跨度,请使用 ui:fragment 或 ui:component 而不是嵌套的 h:panelGroup。
关于java - f :ajax listener executed after render?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8587823/