不处理条件渲染组件中的表单提交 [英] Form submit in conditionally rendered component is not processed

查看:17
本文介绍了不处理条件渲染组件中的表单提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a custom tagfile with a form:

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

我有条件地通过 ajax 呈现它,如下所示:

I'm conditionally rendering it by ajax as below:

<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:

This is the associated backing 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 请求已成功发送.

When I click the first command button, then the updateFlag() method is properly invoked and the second command button is properly shown. But when I then click the second command button, it never hits the printMessage() method. In the web browser's JS console and HTTP traffic monitor I can see that the click event is successfully fired and that the XHR POST request is successfully being sent.

如果我删除 rendered 属性,那么一切都会按预期进行.

If I remove the rendered attribute, then everything works as expected.

这是怎么引起的,我该如何解决?我使用的是 Mojarra 2.1.25.

How is this caused and how can I solve it? I'm using Mojarra 2.1.25.

推荐答案

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

Your concrete problem is caused by 2 facts:

  1. 当 JSF 需要对表单提交操作或提交的输入值进行解码时,它还会检查组件是否已呈现(以防止被黑/篡改请求).
  2. 针对每个 HTTP 请求重新创建请求范围的 bean(一个 ajax 请求也算作一个请求!).

在您的特定情况下,rendered 条件已评估 false 而 JSF 需要解码表单提交操作,因此从未处理未渲染的输入/命令组件.

In your specific case, the rendered condition has evaluated false while JSF needs to decode the form submit action and therefore the non-rendered input/command components are never processed.

将 bean 放入视图范围应该可以修复它.下面的示例假设 JSF 2.x.

Putting the bean in view scope should fix it. Below example assumes JSF 2.x.

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

@ManagedBean
@ViewScoped

以下示例假设 JSF 2.2+ 和 CDI:

And below example assumes JSF 2.2+ with CDI:

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

@Named
@ViewScoped

或者,如果技术要求是将 bean 保留在请求范围内,则在 .调整您的代码段以将其包含在 中.

Or, if the techncial requirement is to keep the bean in request scope, then carry around the condition behind rendered attribute in a <o:inputHidden>. Adjust your snippet to include it in the <h:form>.

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

另见:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆