不处理有条件呈现的组件中的表单提交



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

<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 属性,那么一切都按预期工作。

这是如何造成的,我该如何解决?我正在使用莫哈拉 2.1.25。

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

  1. 当 JSF 需要解码表单提交操作或提交的输入值时,它还会检查组件是否已呈现(作为防止黑客/篡改请求的保护措施)。
  2. 请求作用域的 bean 在每个 HTTP 请求上重新创建(一个 ajax 请求也算作一个请求!

在您的特定情况下,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

或者,如果技术要求是将 bean 保持在请求范围内,则在 <o:inputHidden> 中随身携带rendered属性后面的条件。调整您的代码段以将其包含在<h:form>中。

<o:inputHidden value="#{backingTest.flag}" />

另请参阅:

    命令
  • 按钮/命令链接/ajax 操作/侦听器方法未调用或输入值未设置/更新 - 第 6 点
  • 如何选择合适的豆类范围?

相关内容

  • 没有找到相关文章

最新更新