具有自定义行为的复合组件-全屏模式下的PrimeFaces DataTable



我正在开发一个自定义组合组件,它将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>

最新更新