支持的JSF 2.x顺序处理多个ajax事件的功能对我来说并不起作用。 我得到了以下场景:
h:inputText(CHANGE)
<h:inputText id="consumption_input"
value="#{cc.attrs.consumptionInfo.consumption}">
<f:ajax
render="#{cc.attrs.outerRenderString}"
event="change" listener="#{cc.handleAjaxRequest}" />
</h:inputText>
h:commandButton(ACTION)
<h:commandButton
id="startComparisonButton"
action="#{rateComparisonBean.startRateComparison()}"
value="#{bundle.rateResultOverview_startComparison}">
<!-- This is to avoid mixed requests, ajax and full requests -->
<f:ajax render="@form"/>
</h:commandButton>
如果元素的事件被触发,则两个元素的事件都会被正确处理。
在一次单击中触发两个事件时出现问题(在textInput中输入值,然后单击按钮)。我预计这导致两个同步触发的ajax请求(CHANGE-TextField和ACTION-commandButton)。
不幸的是,只有一个Ajax-Request(Change-TextField),第二个事件似乎完全丢失了。
我已经确保h:commandButton的所有前置条件都已完全填充,如下所示: commandButton/commandLink/ajax action/listener method not invoked or input value not updated
我希望得到关于如何解决这个问题的任何提示。
环境: Glassfish 3,Mojarra 2.1.3-FCS
答案 0 :(得分:3)
JSF AJAX调用是异步的。发送一个AJAX请求(在这种情况下由<h:inputText>
onchange
事件生成)不会阻止JavaScipt继续执行,在这种情况下,触发提交按钮单击,这会触发另一个AJAX请求。尽管如此,AJAX请求确实在客户端排队,按照发送的确切顺序进行处理,这由JSF 2.0 specification第13.3.2章保证。
以下是我的测试用例:
观点:
<h:form id="form">
<h:inputText id="text" value="#{q16363737Bean.text1}">
<f:ajax render="text2" event="change" listener="#{q16363737Bean.ajaxListenerText}"/>
</h:inputText>
<h:commandButton id="button" action="#{q16363737Bean.actionButton}" value="Submit">
<f:ajax render="text1 text3" listener="#{q16363737Bean.ajaxListenerButton}"/>
</h:commandButton>
<br/>
<h:outputText id="text1" value="Text 1: #{q16363737Bean.text1}."/>
<h:outputText id="text2" value="Text 2: #{q16363737Bean.text2}."/>
<h:outputText id="text3" value="Text 3: #{q16363737Bean.text3}."/>
</h:form>
豆子:
@ManagedBean
@ViewScoped
public class Q16363737Bean implements Serializable {
private String text1 = "I'm text 1";//getter + setter
private String text2 = "I'm text 2";//getter + setter
private String text3 = "I'm text 3";//getter + setter
public void ajaxListenerText(AjaxBehaviorEvent abe) {
text2 = "I was modified after inputText AJAX call";
}
public void ajaxListenerButton(AjaxBehaviorEvent abe) {
text1 = "I was modified after AJAX listener call of commandButton";
}
public void actionButton() {
text3 = "I was modified after commandButton AJAX call";
}
}
在检查了一段时间之后,我确实发现很少命令按钮的AJAX调用被吞下并且没有进行UI更新。似乎某处应该有一些竞争条件。这是一个很好的问题,需要进一步调查。
所以,这可能不是一个答案(尽管我认为它最初会是这样),而是一个测试用例的命题。尽管事实上我很少遇到这种行为,但这是一个真实用例,并且值得完全理解正在发生的事情。
答案 1 :(得分:0)
首先感谢分配快速而复杂的回复。
从头开始的第二次测试指出ajax-events排队正确。
所以我再次检查了上面描述的更复杂的场景。跳过的事件接缝的原因与我们的“忙碌叠加”有关。可以把它想象成一堆JavaScript来禁用表单元素,并在长期运行ajax请求时应用叠加层。这是通过应用jsf.ajax.addOnEvent
回拨来完成的。
无论如何,即使我们禁用了一些控件,在'成功'之后表单处于正确状态并且第二个事件可以被处理。
目前,我认为“临时”禁用按钮会影响之后应执行的相关操作事件。
我们目前正在分析这个问题,我将尽快发布最终结果。