我正在尝试使用这个答案中使用的特殊PrimeFaces数据导出器实现:
https://stackoverflow.com/a/14413932/396732
然而,我们的用例有点复杂,例如使用Facelets显示要导出的相应数据表,其中包含行子扩展,其中包含子表。
insiderListManagerDialogs.xhtml:
<ui:include src="insiderListManagerListDialog.xhtml">
<ui:param name="idPrefix" value="il-emp" />
<ui:param name="widgetVarPrefix" value="ilEmp" />
<ui:param name="dialogTitle" value="#{msg['entity.employee.internal.plural.label']}" />
<ui:param name="mapPropertyName" value="insiderListEmployeesMap" />
<ui:param name="sortColumn" value="#{ent.lastTime}" />
<ui:param name="keyColumnsXhtml" value="listDialogInsiderListKeyColumns.xhtml" />
<ui:param name="valueColumnsXhtml" value="listDialogEmployeeValueColumns.xhtml" />
</ui:include>
insiderListManagerListDialog.xhtml:
<p:dialog id="#{idPrefix}-il-view-dialog"
widgetVar="#{widgetVarPrefix}Dialog"
header="#{dialogTitle}"
modal="true"
resizable="false"
appendToBody="true"
onShow="resetFilterInput( '#{idPrefix}' );"
width="1000"
height="750">
<h:form id="#{idPrefix}-il-view-form">
<p:dataTable id="list-entities"
widgetVar="listEntitiesTable"
binding="#{table}"
value="#{insiderListManager.listInstances}"
var="key"
scrollable="true"
scrollHeight="625"
scrollWidth="985"
resizableColumns="true"
expandedRow="#{insiderListManager.listEntitiesRowTogglerOpen}"
filteredValue="#{insiderListManager.filteredEntities}"
sortBy="#{sortColumn}"
styleClass="bx-datatable-header-hidden-m"
tyle="width: 970px;">
<f:facet name="header">
<p:inputText id="globalFilter"
onkeypress="if (event.keyCode == 13) { listEntitiesTable.filter(); return false;}"
size="70"
styleClass="bx-dt-header-element" />
<p:commandButton id="search-btn"
icon="ui-icon bx-icon-search"
value="#{msg['common.action.search.label']}"
process="@this"
onclick="listEntitiesTable.filter(); return false;"
styleClass="bx-dt-header-element" />
<p:commandButton title="#{msg['common.action.excelExport.all.hint']}"
icon="ui-icon bx-icon-excel"
action="#{insiderListManager.exportXls( table )}"
ajax="false"
styleClass="bx-button-border bx-dt-header-element" />
<div class="bx-clear-float" />
</f:facet>
<p:column width="15"
resizable="false">
...
<p:rowExpansion>
<p:dataTable value="#{insiderListManager[mapPropertyName].get(key)}"
var="value">
<ui:include src="#{valueColumnsXhtml}" />
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
<h:panelGroup id="button-panel" layout="block" styleClass="left-button-panel mt-5px">
<p:commandButton id="toggle-button"
icon="#{insiderListManager.listEntitiesRowTogglerOpen ? 'ui-icon ui-icon-circle-triangle-e' : 'ui-icon ui-icon-circle-triangle-s'}"
value="#{insiderListManager.listEntitiesRowTogglerOpen ? msg['common.action.collapseAll.label'] : msg['common.action.expandAll.label']}"
process="@this"
update="@form">
<f:setPropertyActionListener target="#{insiderListManager.listEntitiesRowTogglerOpen}"
value="#{not insiderListManager.listEntitiesRowTogglerOpen}" />
</p:commandButton>
</h:panelGroup>
</h:form>
</p:dialog>
注意
<p:commandButton title="..."
icon="ui-icon bx-icon-excel"
action="#{insiderListManager.exportXls( table )}"
... />
使用绑定数据表,如顶部发布的链接所述。
我们正在使用 JSF 2.1 (Mojarra 2.1.22 - 我们无法切换到MyFaces),它允许表达式从#{idPrefix}-il-view-dialog
构建<ui:param name="idPrefix" value="il-emp" />
之类的ID。
但是,我们正在获得ID唯一性异常:
Caused by: java.lang.IllegalStateException: Component ID il-emp-il-view-form:list-entities:globalFilter has already been found in the view.
at com.sun.faces.util.Util.checkIdUniqueness(Util.java:846)
at com.sun.faces.util.Util.checkIdUniqueness(Util.java:830)
at com.sun.faces.util.Util.checkIdUniqueness(Util.java:830)
at com.sun.faces.util.Util.checkIdUniqueness(Util.java:830)
at com.sun.faces.util.Util.checkIdUniqueness(Util.java:830)
at com.sun.faces.util.Util.checkIdUniqueness(Util.java:830)
at com.sun.faces.util.Util.checkIdUniqueness(Util.java:830)
at com.sun.faces.util.Util.checkIdUniqueness(Util.java:830)
at com.sun.faces.application.view.StateManagementStrategyImpl.saveView(StateManagementStrategyImpl.java:144)
at com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:133)
at com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:419)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.ocpsoft.pretty.faces.application.PrettyViewHandler.renderView(PrettyViewHandler.java:163)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
... 49 more
如果省略了具有显式ID的其他按钮也会发生相同的情况,例如搜索按钮(<p:commandButton id="search-btn" ...
)。
问题:
为什么会发生这种情况?当我们必须为显示的每个用例使用PrimeFaces对话框时,我们如何避免这个问题? (我们有多个对话框)
请注意,删除<p:dataTable ... binding="..."
页面时,该工作正常。
答案 0 :(得分:2)
您基本上将物理上不同的<p:dataTable>
组件绑定到同一个EL变量。如果此EL变量不为null(即已由同一视图中的先前组件设置),则JSF将重用而不是创建新的变量,并在视图构建期间覆盖其所有属性,在视图渲染时间内导致“怪异”行为,并在状态保存期间可能出现重复的组件ID错误。
在特定情况下,您可以使用UIComponent#getNamingContainer()
直接引用子组件内的父<p:dataTable>
组件。
<p:dataTable ... (NO binding!)>
...
<p:comandButton ... action="#{bean.exportXls(component.namingContainer)}" />
它可能会嵌套在另一个 NamingContainer
组件中,然后您需要使用#{component.namingContainer.parent.namingContainer}
。等等多个。