面板组中的命令按钮 [英] Commandbutton in panelgroup

查看:95
本文介绍了面板组中的命令按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

现在-问题是,如果我在这样的<h:panelGroup>中有一个<h:commandButton>元素,那么无论何时提交表单,都只会进行导航,而永远不会调用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参数.

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

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

解决方案

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

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

@ManagedBean
@ViewScoped
public class ManageSquareBean

这样,只要您与同一个视图进行交互,该bean(及其所持有的所有布尔条件)就可以生存.

另请参见:

I have a page which takes a GET parameter, for example: /manageSquare.xhtml?squareName=foobar. This page has a backing bean that is request scoped. To properly initialize the backing bean, the bean includes a initialize method which will be called since the page includes a <f:metadata> with an <f:viewParam> and <f:event type="preRenderView ...>. Sometimes the square does not exist, and some special error message will be shown. Therefore there is a <h:panelGroup rendered="#{squareBean.squareExist}"> element.

Now - the problem is that if I have a <h:commandButton> element inside such a <h:panelGroup> then whenever the form is submitted, only navigation takes place but the action method is never called! How can this be?

Here is some conceptual code (boiled down)

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

and here is the a 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
}

I really do not understand why this is happening. Removing the <panelGroup> and everything is fine. Also, it seems the squareName param is not sent forward when the commandButton is pressed.

Here is a person having the same problem. He solved it using JSTL instead of <panelGroup>, but JSTL will run on build time which is before the initialize method is called.

Please help, I have used many hours on this problem.

解决方案

The rendered attribute of the input and command component and all its parents is re-evaluated during the apply request values phase of the form submit. Since your bean is request scoped, a completely new bean is created upon the submit and therefore the condition of the rendered attribute defaults to false and hence the button is never rendered and thus also never invoked.

Your bean needs to be placed in the view scope.

@ManagedBean
@ViewScoped
public class ManageSquareBean

This way the bean (and all boolean conditions it holds) will live as long as you're interacting with the same view.

See also:

这篇关于面板组中的命令按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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