PrimeFaces和复合组件的问题

时间:2011-07-21 19:19:49

标签: java jsf-2 primefaces composite-component

我有一段类似于“数据表 - 即时行选择”的代码。但是,当我将其分解为复合组件时,不会显示选择值。我怀疑它是由PrimeFaces代码引起的。

以下代码不起作用:
viewApplicationConfig.xhtml

<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:p="http://primefaces.prime.com.tr/ui"
                xmlns:dti="http://java.sun.com/jsf/composite/dti"
                template="../../templates/baseTemplate.xhtml">
    <f:metadata>
        <f:viewParam name="contextApplicationId" value="#{viewApplicationConfig.contextApplicationId}"/>
    </f:metadata>
    <ui:define name="title">#{viewApplicationConfig.pageTitle}</ui:define>
    <ui:define name="content">

        <p:panel id="panel" header="#{viewApplicationConfig.pageTitle}" style="width: 1280px">
            <ui:remove>
                ------ ApplicationFilterCriteriaPanel ----------
            </ui:remove>
            <dti:dtiPanel value="#{viewApplicationConfig.getPanelBean('ApplicationFilterCriteriaPanel')}"
                          toggleable="true" toggleSpeed="500">
                <dti:dtiLayer id="#{viewApplicationConfig.getLayer('ApplicationFilterCriteriaLayer').getLayerId()}">
                    <div style="width: 600px;">
                        <div style="float: left">
                            <h:dataTable
                                    value="#{viewApplicationConfig.getLayerFields('ApplicationFilterCriteriaLayer')}"
                                    var="field">
                                <h:column>
                                    <dti:dtiField field="#{field}" record="#{record}"/>
                                </h:column>
                            </h:dataTable>
                        </div>
                    </div>                
                </dti:dtiLayer>
            </dti:dtiPanel>
            <ui:remove>
                ------ End ApplicationFilterCriteriaPanel ----------
            </ui:remove>
            <ui:remove>
                ------ ApplicationGridPanel ----------
            </ui:remove>
            <dti:dtiPanel value="#{viewApplicationConfig.getPanelBean('ApplicationGridPanel')}"
                          toggleable="true" toggleSpeed="500">
                <dti:dtiLayer id="#{viewApplicationConfig.getLayer('ApplicationGridLayer_GH').getLayerId()}">
                    <div style="width: 600px;">
                        <div style="float: left">
                            <h:dataTable value="#{viewApplicationConfig.getLayerFields('ApplicationGridLayer_GH')}"
                                         var="field">
                                <h:column>
                                    <dti:dtiField field="#{field}" record="#{record}"/>
                                </h:column>
                            </h:dataTable>
                        </div>
                    </div>
                </dti:dtiLayer>
                <ui:remove>
                    ------ DTI GRID ----------
                </ui:remove>
                <dti:dtiGrid columns="#{viewApplicationConfig.getLayerFields('ApplicationGridLayer_GH')}"
                             dataBean="#{viewApplicationConfig}"/>
                <ui:remove>
                    ------ END DTI GRID ----------
                </ui:remove>
            <ui:remove>
                ------ END ApplicationGridPanel ----------
            </ui:remove>
            </dti:dtiPanel>

            <ui:remove>
                ------ Debugging Code --------------
                <h1 class="title ui-widget-header ui-corner-all"
                    style="width: 1200px; margin-left: 20px;"><h:outputLabel
                        value="Welcome #{loginBean.name}"></h:outputLabel></h1>

                <h:outputText value="Theme: #{guestPreferences.theme}"/><br/>
                <h:outputText
                        value="Selected contextApplicationId -- getContextApplicationId(): #{viewApplicationConfig.contextApplicationId}"/>
                <br/>
                <h:outputText value="Grid Header -- getXmlHeader(): #{viewApplicationConfig.xmlHeader}"/> <br/>

                <h:outputText
                        value="Grid Header Fields -- getXmlHeaderFields(): #{viewApplicationConfig.xmlHeaderFields}"/>
                <br/>
                <h:outputText
                        value="Grid Header Layer Fields -- getXmlHeaderLayerFields(): #{viewApplicationConfig.xmlHeaderLayerFields}"/>
                <br/>
                <h:outputText value="Page Fields -- getPageFields(): #{viewApplicationConfig.pageFields}"/> <br/>
                <h:outputText value="Layers  getLayers(): #{viewApplicationConfig.layers}"/> <br/>
                <h:outputText
                        value="Layers  getLayer(ApplicationGridLayer_GH): #{viewApplicationConfig.getLayer('ApplicationGridLayer_GH')}"/>
                <br/>
                <h:outputText
                        value="Layers  getLayerFields(ApplicationGridLayer_GH): #{viewApplicationConfig.getLayerFields('ApplicationGridLayer_GH')}"/>
                <br/>

                <div class="entry">
                    <h:form>
                        <h:commandLink actionListener="#{viewApplicationConfig.navigateToPageConfig}"
                                       value="Click on contextApplicationId"/>

                        <p:dataTable var="record" value="#{viewApplicationConfig.applications}"
                                     paginator="true" rows="5" id="entityTable"
                                     style="width:1220px">

                            <f:facet name="header">
                                Applications -- Size: #{viewApplicationConfig.applications.size()}
                            </f:facet>

                            <p:column headerText="ClientId" style="width:100px">
                                <h:outputText value="#{record.fieldNameList}"/>
                            </p:column>
                        </p:dataTable>
                    </h:form>
                </div>
                ------ End Debugging Code ----------
            </ui:remove>
        </p:panel>
    </ui:define>
</ui:composition>

dtiPanel.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface>
      <composite:attribute name="value" required="true"/>
      <composite:attribute name="toggleable" required="true"/>
      <composite:attribute name="closable"/>
      <composite:attribute name="toggleSpeed"/>
      <composite:attribute name="collapsed"/>
    </composite:interface>

    <composite:implementation>
        <p:panel id="#{cc.attrs.value.id}" header="#{cc.attrs.value.title}"
                toggleable="#{cc.attrs.toggleable}" closable="#{cc.attrs.closable}"
                toggleSpeed="#{cc.attrs.toggleSpeed}"
                collapsed="#{cc.attrs.collapsed}">
            <composite:insertChildren/>
        </p:panel>                              
    </composite:implementation>    
</html>

dtiLayer.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.prime.com.tr/ui"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface>
      <composite:attribute name="id" required="true"/>
      <composite:attribute name="hidden"/>
    </composite:interface>

    <composite:implementation>
        <p:outputPanel id="#{cc.attrs.id}" rendered="#{!cc.attrs.hidden}">    
            <composite:insertChildren/>
        </p:outputPanel>
    </composite:implementation>        
</html>

dtiGrid.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:composite="http://java.sun.com/jsf/composite"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions"
      xmlns:dti="http://java.sun.com/jsf/composite/dti">

<composite:interface>
    <composite:attribute name="columns" required="true"/>
    <composite:attribute name="dataBean" required="true"/>
</composite:interface>

<composite:implementation>
    <div class="entry">
        <h:form id="gridForm">
            <p:ajaxStatus style="width:32px;height:32px;">
                <f:facet name="start">
                    <h:graphicImage value="/core/images/design/ajaxloading.gif"/>
                </f:facet>

                <f:facet name="complete">
                    <h:outputText value=""/>
                </f:facet>
            </p:ajaxStatus>
            <f:facet name="header">
                <p:messages/>
            </f:facet>
            <p:growl id="growl" showDetail="true"/>
            <h:panelGrid columns="2">
                <p:panel header="Export All Data">
                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/excel.png"/>
                        <p:dataExporter type="xls" target="entityTable"
                                        fileName="entityDialog"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/pdf.png"/>
                        <p:dataExporter type="pdf" target="entityTable"
                                        fileName="entityDialog"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/csv.png"/>
                        <p:dataExporter type="csv" target="entityTable"
                                        fileName="entityDialog"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/xml.png"/>
                        <p:dataExporter type="xml" target="entityTable"
                                        fileName="entityDialog"/>
                    </h:commandLink>
                </p:panel>

                <p:panel header="Export Page Data">
                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/excel.png"/>
                        <p:dataExporter type="xls" target="entityTable"
                                        fileName="entityDialog" pageOnly="true"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/pdf.png"/>
                        <p:dataExporter type="pdf" target="entityTable"
                                        fileName="entityDialog" pageOnly="true"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/csv.png"/>
                        <p:dataExporter type="csv" target="entityTable"
                                        fileName="entityDialog" pageOnly="true"/>
                    </h:commandLink>

                    <h:commandLink>
                        <p:graphicImage value="/core/images/primefaces/xml.png"/>
                        <p:dataExporter type="xml" target="entityTable"
                                        fileName="entityDialog" pageOnly="true"/>
                    </h:commandLink>
                </p:panel>
            </h:panelGrid>
            <p:dataTable var="record" value="#{cc.attrs.dataBean.applications}"
                         paginator="true" rows="5" id="entityTable"

                         selection="#{cc.attrs.dataBean.selectedRecord}" selectionMode="single"
                         rowSelectListener="#{cc.attrs.dataBean.onRowSelect}"
                         onRowSelectUpdate="rowForm:display growl"
                         rowUnselectListener="#{cc.attrs.dataBean.onRowUnselect}"
                         onRowUnselectUpdate="growl"
                         onRowSelectComplete="rowDialog.show()" update="rowForm:display"
                         dblClickSelect="true"

                         style="width:1220px">

                <f:facet name="header">
                    Applications -- Size: #{cc.attrs.dataBean.applications.size()}
                </f:facet>
                <c:forEach var="column" items="#{cc.attrs.columns}">
                    <c:choose>
                        <c:when test="#{fn:toUpperCase(column.fieldId)=='SELECT_IND_GH'}">
                            <p:column selectionMode="multiple" style="width:20px"/>
                        </c:when>
                        <c:otherwise>
                            <p:column headerText="#{column.label}" filterBy="#{record.getFieldValue(fn:substringBefore(column.fieldId, '_GH'))}"
                              sortBy="#{record.getFieldValue(fn:substringBefore(column.fieldId, '_GH'))}"  style="width:100px">
                                <c:choose>
                                    <c:when test="#{not empty column.href}">
                                        <h:link outcome="viewApplicationConfig"
                                                value="#{record.getFieldValue(fn:substringBefore(column.fieldId, '_GH'))}">
                                            <f:param name="pageUrl" value="#{column.href}"/>
                                        </h:link>
                                    </c:when>
                                    <c:otherwise>
                                        <h:outputText
                                                value="#{record.getFieldValue(fn:substringBefore(column.fieldId, '_GH'))}"/>
                                                <ui:remove>
                                        <br/>Field Id:  #{column.fieldId}
                                        <br/>Data Type: #{column.datatype}
                                        <br/>Display Type: #{column.displayType}
                                        <br/>Read Only:  #{column.isReadOnly}
                                        <br/>Visible:  #{column.isVisible}
                                        <br/>HREF: #{column.href}
                                        </ui:remove>
                                    </c:otherwise>
                                </c:choose>
                            </p:column>
                        </c:otherwise>
                    </c:choose>
                </c:forEach>
            </p:dataTable>
        </h:form>
        <p:dialog header="Edit Row" widgetVar="rowDialog"
                  resizable="false" width="700">
            <h:form id="rowForm">
                <dti:dtiPanel id="display" value="#{viewApplicationConfig.getPanelBean('ApplicationGridDetailPanel')}"
                              toggleable="true" toggleSpeed="500" collapsed="false">
                    <dti:dtiLayer id="#{viewApplicationConfig.getLayer('ApplicationGridDetailLayer').getLayerId()}">
                        <div style="width: 600px;">
                            <div style="float: left">
                                <h:dataTable
                                        value="#{viewApplicationConfig.getLayerFields('ApplicationGridDetailLayer')}"
                                        var="field">
                                    <h:column>
                                        <ui:remove>
                                            <h:outputText
                                                    value="testX: #{cc.attrs.dataBean.selectedRecord.getFieldValue('baseShortDescription')}"/> /
                                            <h:outputText value="testX 1: #{cc.attrs.dataBean.selectedRecord.size}"/>
                                        </ui:remove>
                                        <dti:dtiField field="#{field}" record="#{cc.attrs.dataBean.selectedRecord}"/>
                                    </h:column>
                                </h:dataTable>
                            </div>
                        </div>
                    </dti:dtiLayer>
                </dti:dtiPanel>
            </h:form>
        </p:dialog>
    </div>            
</composite:implementation>
</html>

dtiField.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions"
      xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
    <composite:attribute name="field" required="true"/>
    <composite:attribute name="record" type="dti.oasis.recordset.Record" required="true"/>
</composite:interface>

<composite:implementation>      
    <ui:remove>
        <h:outputText value="FieldName 0: #{cc.attrs.record.getFieldNameList().get(0)}"/> / <h:outputText
            value="test 1: #{cc.attrs.record.size()}"/>
    </ui:remove>
    <p:outputPanel rendered="#{cc.attrs.field.isVisible and !fn:endsWith(cc.attrs.field.fieldId, '_GH')}">
        <div id="#{cc.clientId}">
            <h:panelGrid columns="2">
                <div style="width: 100%">
                    <div style="float: left; #{cc.attrs.field.style}">
                        #{cc.attrs.field.label}
                    </div>
                    <div style="float: right">

                        <h:outputText value="#{cc.attrs.record.getFieldValue(cc.attrs.field.fieldId)}" rendered="#{cc.attrs.field.isReadOnly}"/>

                        <h:inputText rendered="#{cc.attrs.field.displayType == 'TEXT' and !cc.attrs.field.isReadOnly}"
                                     value="#{cc.attrs.record.getFieldValue(cc.attrs.field.fieldId)}"/>
                        <h:selectOneMenu rendered="#{cc.attrs.field.displayType == 'SELECT' and !cc.attrs.field.isReadOnly}">
                            <f:selectItems/>
                        </h:selectOneMenu>
                        <h:selectBooleanCheckbox rendered="#{cc.attrs.field.displayType == 'CHECKBOX' and !cc.attrs.field.isReadOnly}"
                                                 value="#{cc.attrs.record.getFieldValue(cc.attrs.field.fieldId)}"/>                        
                           <ui:remove>               
                        <br/>Display Type: #{cc.attrs.field.displayType}
                        <br/>Visible: #{cc.attrs.field.isVisible}
                        <br/>Read Only: #{cc.attrs.field.isReadOnly}
                        <br/>Field Id: #{cc.attrs.field.fieldId}
                        <br/>Rows: #{cc.attrs.field.rowNum}
                        <br/>Columns: #{cc.attrs.field.colNum}
                        <br/>Field Value: #{cc.attrs.record.getFieldValue(cc.attrs.field.fieldId)}
                        </ui:remove> 
                    </div>
                </div>
            </h:panelGrid>
        </div>
    </p:outputPanel>
</composite:implementation>
</html>

bean类如下所示:

package com.dti.admin.cwb.appconfigmgr.view;

import com.dti.admin.view.BaseAdminManagedBean;
import com.dti.view.ManagedBeanUtils;
import dti.admin.cwb.appconfigmgr.AppConfigManager;
import dti.oasis.recordset.Record;
import dti.oasis.recordset.RecordSet;

import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpServletRequest;

import java.io.Serializable;
import java.util.List;

@Component("viewApplicationConfig")
@Scope("request")
public class ViewApplicationConfig extends BaseAdminManagedBean implements Serializable {
    private AppConfigManager appConfigManager;
    private String contextApplicationId;
    private List<Record> applications;
    private RecordSet applicationRecordSet;

    //////
    private Record selectedRecord;

    public Record getSelectedRecord() {
System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- getSelectedRecord --");
        if(selectedRecord!=null){

System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- getSelectedRecord -- getRecordNumber: "+
            selectedRecord.getRecordNumber());
        }
        return selectedRecord;
    }

    public void setSelectedRecord(Record selectedRecord) {
        this.selectedRecord = selectedRecord;
    }
  //////

    public void onRowSelect(SelectEvent event) {
        System.out.println("onRowSelect");
        FacesMessage msg = new FacesMessage("Entity Selected",
           (String)((Record) event.getObject()).getFieldValue("baseShortDescription"));

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onRowUnselect(UnselectEvent event) {
        System.out.println("onRowUnselect");        
        FacesMessage msg = new FacesMessage("Entity Unselected",
            (String)((Record) event.getObject()).getFieldValue("baseShortDescription"));

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }    
    ///////////////////
    public ViewApplicationConfig() {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "ViewApplicationConfig()");
    }


    @Autowired()
    public ViewApplicationConfig(AppConfigManager appConfigManager) {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- "
                + "ViewApplicationConfig(AppConfigManager appConfigManager)");

        this.appConfigManager = appConfigManager;

        this.setPageId("MaintainApplicationConfig");
        this.setAnchorColumnName("applicationId");
    }


    @PostConstruct
    public void onLoad() throws Exception {

        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "onLoad()");

        HttpServletRequest request = ManagedBeanUtils.getHttpServletRequest();

        init(request);


        //Grid Header
        setXmlHeader(getGridHeader(request));

        //From Action Class
        Record inputRecord = getInputRecord(request);

        //From prime-movicollector -- sort of
        if(applicationRecordSet == null) {
            applicationRecordSet = appConfigManager.loadAllWebApplications(inputRecord);
            applications = ManagedBeanUtils.convertRecordSetToList(applicationRecordSet);
        }
        //

        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " + applications.size());
    }

    @PreDestroy
    public void onUnload() {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "onUnload()");
        terminate();
    }


    public void navigateToPageConfig(ActionEvent actionEvent) {
        System.out.println("navigateToPageConfig("+contextApplicationId+")");
        String pageUrl = "/pageconfigmgr/maintainPageConfig.do?contextApplicationId=" + contextApplicationId;
        navigateToPage(pageUrl);
    }

    public AppConfigManager getAppConfigManager() {
        return appConfigManager;
    }

    public void setAppConfigManager(AppConfigManager appConfigManager) {
        this.appConfigManager = appConfigManager;
    }

    public List<Record> getApplications() {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "getApplications()");
        return applications;
    }

    public void setApplications(List <Record> applications) {
        System.out.println(new java.sql.Timestamp(System.currentTimeMillis()) + " -- "
                + this.getClass().getName() + " -- " + "setApplications(RecordSet applications)");
        this.applications = applications;
    }

    public RecordSet getApplicationRecordSet() {
        return applicationRecordSet;
    }

    public void setApplicationRecordSet(RecordSet applicationRecordSet) {
        this.applicationRecordSet = applicationRecordSet;
    }

    public String getContextApplicationId() {
        return contextApplicationId;
    }

    public void setContextApplicationId(String contextApplicationId) {
        this.contextApplicationId = contextApplicationId;
    }

}

是否有人使用复合组件有类似的问题,p:dataTable和p:dialog?

1 个答案:

答案 0 :(得分:0)

我没有仔细阅读整个代码,因为您没有指向我的特定代码,例如“当我点击<p:commandButton id="someButton" ...”所以我只是'猜测'

我看到支持bean是使用Spring的容器进行请求作用的。我认为你遇到的问题是bean有一个请求的生命周期。如果你正在做AJAX之类的事情,比如在数据表中选择行,你需要一个视图范围的bean。有关不同范围的解释,请查看 this question

我也猜测你现在想要使用视图范围的bean,我知道Spring没有你可以使用的@Scope("view")。幸运的是Cagatay Civici来救援并发布了 a solution on his blog