h:commandLink 动作和 f:ajax 监听器的调用顺序

Posted

技术标签:

【中文标题】h:commandLink 动作和 f:ajax 监听器的调用顺序【英文标题】:Call order of h:commandLink action and f:ajax listener 【发布时间】:2015-05-08 04:55:56 【问题描述】:

这是我的标记:

<h:commandLink value="#partial" action="#hello.setCurrentPartial(partial)">
    <f:ajax render="include" listener="#hello.renderFragments"/>
</h:commandLink>

我尝试在 Mojarra-2.2.8(wildfly 8.2.0.Final 内置)和 MyFaces-2.2.7(按照指导安装 here)中运行此页面。令人惊讶的是,当点击链接时,mojarra 先调用hello.renderFragments,然后调用hello.setCurrentPartial,但MyFaces 采用相反的顺序,即先调用hello.setCurrentPartial

所以我的问题是JSF Spec中是否定义了action和ajax listener的调用顺序。如果定义了顺序,哪个实现是正确的?

【问题讨论】:

这确实出乎意料。作为解决方法,将&lt;f:ajax listener&gt; 移动到&lt;h:commandLink actionListener&gt;。我会向 JSF 规范人员询问这个差异。 @BalusC 我猜 mojarra 行为是理想的行为(请纠正我,因为我不太确定),不应该在操作方法之前调用侦听器吗? @Tarik:我在规范中找不到有关此行为的参考,但 Mojarra 行为确实更直观/自然/预期。首先是侦听器,然后是动作,就像 actionListener/action 的工作方式一样。我把 EG 留给了mail。 @BalusC 好的,顺便说一句,你刚刚收到了第一个回复 @Tarik:是的,只是我的同事提到了一项协议。 【参考方案1】:

根据EG discussion,Mojarra 的行为是正确的,因为它与actionListener/action 的工作方式一致。 MyFaces 的人在上面创建了一个issue,预计这将在下一个 MyFaces 版本中得到修复。并且,JSF 规范应该在这方面更加明确,这将继续进行。

同时,如果您希望 Mojarra 和 MyFaces 中的行为与方法调用顺序相同,请将 &lt;f:ajax listener&gt; 移动到 &lt;h:commandLink actionListener&gt;

<h:commandLink value="#partial" actionListener="#hello.renderFragments" action="#hello.setCurrentPartial(partial)">
    <f:ajax render="include" />
</h:commandLink>

另见:

Differences between action and actionListener

【讨论】:

一如既往的快速响应和彻底解释问题和解决方案。如果做 JSF 的原因只有一个,那就是@BalusC。 不客气,感谢您质疑这种差异,它只会让 JSF 变得更好。

以上是关于h:commandLink 动作和 f:ajax 监听器的调用顺序的主要内容,如果未能解决你的问题,请参考以下文章

a4j:commandLink 和 h:commandLink 的区别

h:commandLink 不工作

如何防止点击 <h:commandLInk> 时页面刷新

JSF。转换 h:commandLink 显示的值

如何在执行 JSF <h:commandLink> 操作之前执行 Javascript? [复制]

为 <h:outputLink>、<h:commandLink> 等添加默认参数