2014-09-04 47 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> 

这是一个例子。