不处理有条件渲染组件中的表单提交

时间:2013-09-13 09:11:15

标签: ajax jsf jsf-2 conditional-rendering

我有一个带有表单的自定义标记文件:

<h:form>
    <h:commandButton value="click">
        <f:ajax event="click" listener="#{bean[method]}" />
    </h:commandButton>
</h:form>

我有条件地用ajax渲染它,如下所示:

<h:panelGroup id="test">
  <h:form>
    <h:commandButton value="click">
      <f:ajax event="click" listener="#{backingTest.updateFlag}" render=":test"/>
    </h:commandButton>
  </h:form>
  <h:panelGroup rendered="#{backingTest.flag}">
    <my:customtag bean="#{backingTest}" method="printMessage"/>
  </h:panelGroup>
</h:panelGroup>

这是关联的支持bean:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class BackingTest {

    private boolean flag = false;

    public void printMessage() {
        System.out.println("hello");
    }

    public void updateFlag() {
        flag = true;
    }

    public boolean getFlag() {
        return flag;
    }
}

当我单击第一个命令按钮时,正确调用updateFlag()方法并正确显示第二个命令按钮。但是,当我单击第二个命令按钮时,它永远不会点击printMessage()方法。在Web浏览器的JS控制台和HTTP流量监视器中,我可以看到click事件已成功触发,并且已成功发送XHR POST请求。

如果我删除了rendered属性,那么一切都按预期工作。

这是如何引起的,我该如何解决?我正在使用Mojarra 2.1.25。

1 个答案:

答案 0 :(得分:4)

您的具体问题是由2个事实引起的:

  1. 当JSF需要解码表单提交操作时,它还会检查组件是否已呈现(以防止被黑/篡改的请求)。
  2. 在每个HTTP请求上重新创建请求范围的bean(ajax请求也算作一个请求!)。
  3. 在您的特定情况下,rendered条件已评估false,而JSF需要解码表单提交操作,因此永远不会处理非呈现的输入/命令组件。

    将bean置于视图范围内应该修复它。下面的例子假设是JSF 2.x。

    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    @ManagedBean
    @ViewScoped
    

    以下示例假定JSF 2.2+与CDI:

    import javax.inject.Named;
    import javax.faces.view.ViewScoped;
    
    @Named
    @ViewScoped
    

    另见: