我正在使用Primefaces 3.4和JSF 2.1,我试图让p:panel项目出现并消除p:oneselectmenu
的选择。我想在面板中显示p:datatable
并动态填充,这就是我使用面板的原因。数据表的功能很好,但是面板没有。我尝试连接"渲染"面板上的选项,其变量随菜单的每个选择的变化而变化,但没有任何反应。我也尝试了p:outputpanel
,但没有发生任何事情。所以我尝试使用具有相同操作的按钮,但又失败了。这是我的代码:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<ui:composition template="/template.xhtml">
<ui:define name="title">
#{msg.teaching}: #{msg.socialSecurity}
</ui:define>
<ui:define name="body">
<h:form id="form">
<p:messages id="messages" autoUpdate="true"/>
<p:panel id="selectSocialSecurityPanel" rendered="true">
<p:panelGrid>
<p:row>
<p:column>
<p:selectOneMenu value="#{selectOneMenuSocialSecurityTeachingBean.choice}">
<p:ajax update="socialSecurityDataTablePanel, socialSecurityDataTable, toUpdate" listener="#{dataTableSocialSecurityBean.updateTable()}"/>
<f:selectItem itemLabel="#{msg.select}" itemValue=""/>
<f:selectItems value="#{selectOneMenuSocialSecurityTeachingBean.socialSecurityTeachingList}"/>
</p:selectOneMenu>
</p:column>
<p:column>
<p:commandButton value="#{msg.find}" actionListener="#{dataTableSocialSecurityBean.updateTable()}" update="socialSecurityDataTablePanel, socialSecurityDataTable, toUpdate" id="button">
<f:ajax render="toUpdate"/>
</p:commandButton>
</p:column>
</p:row>
</p:panelGrid>
</p:panel>
<p:outputPanel id="toUpdate" rendered="#{dataTableSocialSecurityBean.rendered}" autoUpdate="true">
<p:panel id="socialSecurityDataTablePanel">
<p:dataTable id="socialSecurityDataTable" var="unit" value="#{dataTableSocialSecurityBean.socialSecurityList}">
<p:columns value="#{dataTableSocialSecurityBean.columns}" var="column" columnIndexVar="colIndex">
<f:facet name="header">
#{column.header}
</f:facet>
#{unit[column.property]}
</p:columns>
</p:dataTable>
</p:panel>
</p:outputPanel>
</h:form>
</ui:define>
</ui:composition>
</h:body>
和此:
@ManagedBean
@ViewScoped
public final class DataTableSocialSecurityBean implements Serializable {
private String choice;
private List<Unit> socialSecurityList;
private boolean rendered;
private List<ColumnModel> columns = new ArrayList<ColumnModel>();
public boolean getRendered(){
System.out.println("DataTableSocialSecurityBean getRendered");
System.out.println("DataTableSocialSecurityBean getRendered="+rendered);
return rendered;
}
public void updateTable() {
rendered=true;
socialSecurityList = new ArrayList<Unit>();
createDynamicColumns();
populateDataTable(socialSecurityList);
}
}
有什么想法吗?
答案 0 :(得分:6)
您的rendered
字段最初为false
,因此不会在第一个视图中呈现该面板。在初始HTML的该视图中,没有标记为toUpdate
的标记,因此无法呈现。我建议你将这个panel
置于某个h:panelGroup
内并重新呈现此组件:
<h:panelGroup id="myContainer" layout="block">
<p:outputPanel id="toUpdate" rendered="#{dataTableSocialSecurityBean.rendered}" autoUpdate="true">
</p:outputPanel>
</h:panelGroup>
您使用render="myContainer"
。我还建议您使用p:ajax
而不是f:ajax
作为primefaces组件。
您可以尝试添加效果添加p:effect
组件作为p:outputPanel
的孩子:
<p:effect type="explode" event="load"/>
有关完整事件列表,请参阅PrimeFaces用户指南。
答案 1 :(得分:2)
要使渲染事件按您的方式运行,组件应该是可见的(存在于dom中)。最常见的hack是将呈现的属性应用于内部组件(不是输出面板,而是内部的面板)
<p:outputPanel id="toUpdate" autoUpdate="true">
<p:panel id="socialSecurityDataTablePanel" rendered="#{dataTableSocialSecurityBean.rendered}">
</p:panel>
</p:outputPanel>
这样,你的outputPanel每次都可见(存在于DOM中)并且可以告诉它的子节点根据条件自我渲染。