我有一个采用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
方法之前的构建时运行。
请帮助,我已经花了很多时间解决这个问题。
答案 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>