我正在开发一个自定义组合组件,它将primeface Data Table与我需求中的其他一些特性一起重用。其中一个特性是以全屏模式显示Table。为此,我开发了三个自定义组件:
外部容器
<composite:interface componentType="m3DataTable">
<composite:attribute name="rendered" targets="idListPanel idListPanelFullScreen"/>
<composite:attribute name="for" targets="idListPanelFullScreen" required="true"/>
<composite:attribute name="my" targets="idListPanelFullScreen" default="left topo"/>
<composite:attribute name="at" targets="idListPanelFullScreen" default="left topo"/>
</composite:interface>
<composite:implementation>
<span id="#{cc.clientId}">
<p:overlayPanel id="idListPanelFullScreen" for="#{cc.attrs.for}" appendToBody="true" dynamic="true" styleClass="m3PanelListaDatiOverlay" binding="#{cc.m3DataTableOverlayPanel}" widgetVar="#{cc.id}widgetVarOverlay" >
</p:overlayPanel>
<p:panel id="idListPanel" styleClass="m3PanelListaDati" binding="#{cc.m3DataTablePanel}">
<composite:insertChildren></composite:insertChildren>
</p:panel>
</span>
</composite:implementation>
头
<composite:interface componentType="m3DataTableHeader">
</composite:interface>
<composite:implementation>
<span id="#{cc.clientId}">
<p:commandLink id="idFullScreen" ajax="true" actionListener="#{cc.actionListener}">
<p:graphicImage id="fullScreen" value="../images/empty.png" styleClass="ico_full_screen"/>
</p:commandLink>
</span>
</composite:implementation>
然后我有一个网格组件,显示表在外部组件。我不报告网格组件代码,因为它对讨论没有用处。
最后我在我的测试页面使用组件:
<m3:m3DataTable id="idListCar" my="left top" at="left top" for=":ancora" rendered="#{lazyTableComponentBean.datasource.size()>0}">
<m3:m3DataTableHeader id="listaHeader" title="Test Table" rendered="#{lazyTableComponentBean.datasource.size()>0}">
</m3:m3DataTableHeader>
<m3:m3DataTableGrid id="idListaAttivitaGrid" var="car" selection="#{lazyTableComponentBean.selectedCar}" value="#{lazyTableComponentBean.listaCars}" rowkey="#{car.name}">
<p:column headerText="Progressivo">
<h:outputText value="#{car.num}" />
</p:column>
<p:column headerText="Name">
实现全屏视图模式的想法是,点击"idFullScreen"组件链接,idListPanel被逆转成OverlayPanel (idlistafulscreen)。受BalusC具有多个输入字段的复合组件的启发,我开发了两个支持组件,一个用于m3DataTable,另一个用于m3DataTableHeader。
M3DataTableHeader类,为idFullScreen实现actionListener:
@FacesComponent("m3DataTableHeader")
public class M3DataTableHeader extends UINamingContainer{
public void actionListener(ActionEvent e){
M3DataTable ccParent = (M3DataTable) getCompositeComponentParent(this);
Collection<String> componentToUpdate = new ArrayList<String>();
if(ccParent!=null){
if(getStateHelper().get("isFullScreen")!=null && (Boolean)getStateHelper().get("isFullScreen")==true){
ccParent.setIsFullScrenn(false);
}
else
ccParent.setIsFullScrenn(true);
}
if(e.getComponent().getChildCount()>0 && e.getComponent().getChildren().get(0) instanceof GraphicImage){
GraphicImage child = (GraphicImage)e.getComponent().getChildren().get(0);
child.setStyleClass("ico_exit_full_screen");
componentToUpdate.add(child.getId());
componentToUpdate.add(e.getComponent().getId());
componentToUpdate.add(ccParent.getClientId());
}
RequestContext.getCurrentInstance().update(componentToUpdate);
}
在m3DataTable支持组件中,在渲染阶段I复制面板子组件到Overlay:
@Override
public void encodeChildren(FacesContext context) throws IOException {
if(getIsFullScrenn()!=null && getIsFullScrenn()){
List<UIComponent> panelChildren = getM3DataTablePanel().getChildren();
getM3DataTableOverlayPanel().getChildren().addAll(panelChildren);
RequestContext.getCurrentInstance().update(getClientId());
RequestContext.getCurrentInstance().execute(getId()+"widgetVarOverlay.show()");
}
super.encodeChildren(context);
}
加上我需要用户可以点击idFullScreen命令链接在正常模式下恢复视图,所以在该行动期间,我可以复制回覆盖面板的孩子到面板。一切工作正常,但在视图更新和覆盖显示后,CommandLink不再触发actionListener方法。
我不确定这是实现此行为的最佳解决方案,可能我错过了什么,任何帮助都应该是有用的。
我正在使用PirmeFaces 3.5.23, mojarra 2.1.21和我正在开发一个portlet在Liferay 6.1.3ga3和桥3.1.3ga4
谢谢你的帮助
我找到了一个解决方案:
我改变外部容器,我从覆盖面板中删除了dynamic="true"和appendToBody="true",一切都很好
<composite:implementation>
<span id="#{cc.clientId}">
<p:overlayPanel id="idListPanelFullScreen" for="#{cc.attrs.for}" styleClass="m3PanelListaDatiOverlay" binding="#{cc.m3DataTableOverlayPanel}" widgetVar="#{cc.id}widgetVarOverlay" >
</p:overlayPanel>
<p:panel id="idListPanel" styleClass="m3PanelListaDati" binding="#{cc.m3DataTablePanel}">
<composite:insertChildren></composite:insertChildren>
</p:panel>
</span>