面板组中的命令按钮

时间:2011-09-16 07:01:29

标签: jsf-2

我有一个采用GET参数的页面,例如:/manageSquare.xhtml?squareName=foobar。此页面有一个请求作用域的支持bean。为了正确初始化支持bean,bean包含一个initialize方法,该方法将被调用,因为该页面包含<f:metadata> <f:viewParam><f:event type="preRenderView ...>。有时广场不存在,并会显示一些特殊的错误消息。因此,有一个<h:panelGroup rendered="#{squareBean.squareExist}">元素。

现在 - 问题是,如果我在<h:commandButton>内有一个<h:panelGroup>元素,那么每当提交表单时,只会进行导航,但永远不会调用action方法!怎么会这样?

这是一些概念性代码(简化)

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:fn="http://java.sun.com/jsp/jstl/functions"
            template="../template.xhtml">
<ui:param name="title" value="Square"/>
<f:metadata>
    <f:viewParam name="squareName" value="#{manageSquareBean.squareName}"/>
    <f:event type="preRenderView" listener="#{manageSquareBean.initialize}"/>
</f:metadata>
<ui:define name="content">
    <h1>Manage square <h:outputText escape="true" value="#{manageSquareBean.squareName}"/></h1>
    <h:panelGroup rendered="#{!manageSquareBean.squareExists}">
        <span class="error">Square does not exist</span>
    </h:panelGroup>
    <h:panelGroup rendered="#{manageSquareBean.squareExists}">
        <h:form>           
            <h:commandButton action="#{manageSquareBean.addUsersToSquare}" value="Add users">
                <f:param name="squareName" value="#{manageSquareBean.squareName}"/>
            </h:commandButton>
         </h:form>
    </h:panelGroup>
</ui:define>
</ui:composition>

这是一个managedBean:

@RequestScoped
@ManagedBean
public class ManageSquareBean
{
    private String squareName;

    private boolean squareExists;
    private List<String> usersToAdd;

    public void initialize()
    {
        // Find out if squareName exists
        squareExists = squareExists(squareName);
    }

    public String addUsersToSquare()
    {
        // Do something
    }

    // Getters and setters
}

我真的不明白为什么会这样。删除<panelGroup>,一切都很好。此外,当按下commandButton时,似乎squareName参数不会向前发送。

Here是一个有同样问题的人。他使用JSTL而不是<panelGroup>解决了它,但JSTL将在调用initialize方法之前的构建时运行。

请帮助,我已经花了很多时间解决这个问题。

2 个答案:

答案 0 :(得分:2)

在表单提交的应用请求值阶段,将重新评估输入和命令组件及其所有父项的rendered属性。由于bean是请求作用域,因此在提交时会创建一个全新的bean,因此rendered属性的条件默认为false,因此该按钮永远不会呈现,因此也永远不会被调用。

您的bean需要放在视图范围内。

@ManagedBean
@ViewScoped
public class ManageSquareBean

这样,只要您与同一视图交互,bean(以及它所拥有的所有布尔条件)就会存在。

另见:

答案 1 :(得分:0)

我确定panelGroup不是问题所在。

我有2条建议:

1)检查您是否有继承表格。有时,通过模板方法,表单元素会以另一种形式存在。 JSF无法正确处理

2)也许您需要使用define标记和名称元数据包装f:metadata。

http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/f/metadata.html

<ui:define name="metadata">
<f:metadata>
    <f:viewParam name="squareName" value="#{manageSquareBean.squareName}"/>
    <f:event type="preRenderView" listener="#{manageSquareBean.initialize}"/>
</f:metadata>
</ui:define>