2014-09-04 45 views
12

我使用Primefaces 5.0創建動態數據表。Primefaces靜態和動態列在數據表中

我的DataObject有一些必填字段和一個可選的「tupel」(鍵值對)列表。可選列表的大小可能有所不同。因此我需要一個動態機制來顯示Primefaces.DataTable中的DataObject列表。

我的做法是這樣的:

public class DataObject { 
    private String staticval1; 
    private String staticval2; 

    private List<Tupel> optionalValues; 


    // .. getter, setter, hashCode, toString..... 
} 

public class Tupel{ 
    private String id; 
    private String value; 
} 

@ManagedBean 
@ViewScoped 
public class TableOverviewBean { 
    private List<DataObject> data; 

    @EJB 
    private IMyDao myDao; 

    @PostConstruct 
    public void init() { 
     data = myDao.findAll(); 
    } 

    public List<DataObject> getData() { 
     return data; 
    } 

    public void setData(List<DataObject> data) { 
     this.data = data; 
    } 
} 
<h:form> 
     <p:dataTable value="#{tableOverviewBean.data}" var="data"> 
      <p:column headerText="static1"> 
       <h:outputText value="#{data.staticval1}" /> 
      </p:column> 

      <p:column headerText="static2"> 
       <h:outputText value="#{data.staticval2}" /> 
      </p:column> 

      <p:columns value="#{data.optionalValues}" var="opt" headerText="#{opt.id}"> 
       <h:outputText value="#{opt.value}" /> 
      </p:columns> 
     </p:dataTable> 
    </h:form> 

但是,這是行不通的。動態列不會呈現。 我該如何解決我的問題?

編輯: 預期結果:

staticval1 | staticval2 | dynamic_id1 | dynamic_id2 | ... | dynmic_idn 
---------------------------------------------------------------------- 
static1a | static2a | dyna_value1a| dyna_value2a | ... | dyna_valu3a 
static1b | static2b | dyna_value1b| dyna_value2b | ... | dyna_valu3b 
static1c | static2c | dyna_value1c| dyna_value2c | ... | dyna_valu3c 

回答

16

這是不可能的定義基於行的數據列。想象一下,第1行有2列,第2行有6列,第3行有1列,等等,你會如何在HTML中產生技術上有效的表格?每一行必須具有相同數量的列。

您已經2個選項,這取決於是否可以更改型號或不:

  1. 如果你不能改變的模式,那麼你需要通過一個單一的<p:column>和循環到替換<p:columns>#{data.optionalValues}使用嵌套循環與例如<ui:repeat>甚或另一<p:dataTable><p:columns>

    <p:column> 
        <p:dataTable value=""><!-- Empty string as value forces 1 row. --> 
         <p:columns value="#{data.optionalValues}" var="opt" headerText="#{opt.id}"> 
          #{opt.value} 
         </p:columns> 
        </p:dataTable> 
    </p:column> 
    
  2. 如果你可以改變模型,那麼你就需要讓<p:columns value>點到Bean屬性,而不是到行屬性​​,因此它的準確的每一行相同。如果將List<Tupel> optionalValues替換爲Map<String, Tupel> optionalValues(其中鍵爲Tupel#id),並將List<String>屬性添加到包含所有可用的Tupel#id值的bean中,則此方法有效。

    <p:columns value="#{tableOverviewBean.availableTupelIds}" var="id" headerText="#{id}"> 
        #{data.optionalValues[id].value} 
    </p:columns> 
    
+0

這兩種解決方案都不能真正解決我的問題。我添加了一個示例輸出到我的問題。有沒有辦法得到這樣的桌子? – veote 2014-09-08 09:14:45

+0

您是否閱讀過第一段?如果你想實現你需要的佈局,你必須將數據從一行移動到一個bean並提供固定數量的列。 – BalusC 2014-09-08 09:34:16

+0

是的,我讀過。我的行具有相同數量的列。但是,如果我獲得另一個數據集,列的數量可能會有所不同。例如。有一次有10個可選值(每個數據對象有10個)。另一組可能有8個optinal值。 – veote 2014-09-08 09:49:06

0

的java:

@Named 
@ViewScoped 
public class LiveRangeService implements Serializable { 
    private List< Map<String, ColumnModel> > tableData; 
    private List<ColumnModel> tableHeaderNames; 


    public List<Map<String, ColumnModel>> getTableData() { 
     return tableData; 
    } 
    public List<ColumnModel> getTableHeaderNames() { 
     return tableHeaderNames; 
    } 

    public void PlayListMB() { 
     tableData = new ArrayList< Map<String, ColumnModel> >(); 

     //Generate table header. 
     tableHeaderNames = new ArrayList<ColumnModel>(); 
     for (int j = 0; j < 5; j++) { 
       tableHeaderNames.add(new ColumnModel("header "+j, " col:"+ String.valueOf(j+1))); 
     } 

     //Generate table data. 
     for (int i = 0; i < 10; i++) { 
      Map<String, ColumnModel> playlist = new HashMap<String, ColumnModel>(); 
      for (int j = 0; j < 5; j++) { 
       playlist.put(tableHeaderNames.get(j).key,new ColumnModel(tableHeaderNames.get(j).key,"row:" + String.valueOf(i+1) +" col:"+ String.valueOf(j+1))); 
      } 
      tableData.add(playlist); 
     } 
    } 

    static public class ColumnModel implements Serializable { 

     private String key; 
     private String value; 

     public ColumnModel(String key, String value) { 
      this.key = key; 
      this.value = value; 
     } 

     public String getKey() { 
      return key; 
     } 

     public String getValue() { 
      return value; 
     } 
    } 

/////////////////////////////// /////////////

   <h:form> 

        <p:dataTable id="tbl" var="result" 
         value="#{liveRangeService.tableData}" 
         rendered="#{not empty liveRangeService.tableData}" 
         rowIndexVar="rowIndex" 
         > 

         <f:facet name="header"> header table </f:facet> 

         <p:column> 
          <f:facet name="header"> 
           <h:outputText value="序號" /> 
          </f:facet> 
          <h:outputText value="#{rowIndex+1}" /> 
         </p:column> 

         <p:columns value="#{liveRangeService.tableHeaderNames}" 
          var="mycolHeader" columnIndexVar="colIndex"> 
          <f:facet name="header"> 
           <h:outputText value="#{mycolHeader.value}" /> 

          </f:facet> 
          <h:outputText value="#{result[mycolHeader.key].value}" /> 
          <br /> 
         </p:columns> 

        </p:dataTable> 
       </h:form> 

這是一個例子。