【问题标题】:JSF ajax event queue doesn't work on action-event after change-eventJSF ajax 事件队列在更改事件后对动作事件不起作用
【发布时间】:2013-04-28 03:24:27
【问题描述】:

支持的 JSF 2.x 顺序处理多个 ajax 事件的特性对我不起作用。 我得到了以下场景:

  1. h:inputText(更改)

    <h:inputText id="consumption_input"
       value="#{cc.attrs.consumptionInfo.consumption}">
      <f:ajax
         render="#{cc.attrs.outerRenderString}"
         event="change" listener="#{cc.handleAjaxRequest}" />
    </h:inputText>
    
  2. h:commandButton(动作)

    <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

【问题讨论】:

  • 有趣...您是否在一个易于复制的小型应用程序中验证了这一点?是否可以将 Mojarra 换成 MyFaces 并查看是否有相同的行为?
  • 你有没有遇到过 expected 行为,同时触发了两个(动作)监听器?
  • 您找到解决方案了吗?我也面临同样的问题。

标签: ajax jsf jsf-2 commandbutton


【解决方案1】:

JSF AJAX 调用是异步的。发送一个 AJAX 请求,在这种情况下由 &lt;h:inputText&gt; 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 更新。似乎某处应该有一些竞争条件。这是一个很好的问题,需要进一步调查。

所以,这可能不是一个答案(虽然我最初认为它会是),而是一个测试用例的命题。尽管我很少遇到这种行为,但这是一个真实的用例,值得充分了解发生了什么。

【讨论】:

    【解决方案2】:

    首先感谢您快速而周到的回复。

    从头开始的第二个测试指出,ajax 事件已正确排队。

    所以我再次检查了上述更复杂的场景。跳过事件接缝的原因与我们的“忙覆盖”有关。把它想象成一堆 JavaScript,它禁用表单元素并在长时间运行的 ajax 请求期间应用覆盖。这是通过应用jsf.ajax.addOnEvent 回调来完成的。

    不管怎样,即使我们禁用了一些控件,在“成功”之后表单处于正确状态并且可以处理第二个事件。

    目前我认为“暂时”禁用的按钮会破坏应该在之后执行的相关操作事件。

    我们目前正在分析这个问题,我会尽快发布最终结果。

    【讨论】:

    • 您找到解决方案了吗?我知道这已经发布了很多,但我面临同样的问题。如果不删除“繁忙的覆盖”或对其进行延迟,我将找不到解决方案。
    • 不幸的是,我们想要运行它的业务不存在了。但这不仅仅是因为覆盖:-)
    猜你喜欢
    • 2016-09-23
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    • 2011-01-25
    • 2012-12-10
    相关资源
    最近更新 更多