Primefaces数据表格中的静态和动态列

14

我正在使用Primefaces 5.0创建一个动态数据表。

我的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
2个回答

25

根据行数据无法定义列。想象一下第1行有2列,第2行有6列,第3行有1列等等,你怎么能产生一个在 HTML 中技术上有效的表格呢?每行必须有相同数量的列。

根据您是否可以更改模型,您有两个选项:

  1. 如果您不能更改模型,则需要使用单个<p:column>替换该<p:columns>,并使用嵌套循环(例如使用<ui:repeat>或甚至另一个<p:dataTable><p:columns>)遍历#{data.optionalValues}
<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>
如果您可以更改模型,则需要将<p:columns value>指向一个bean属性而不是行属性,以便每一行都完全相同。如果您将List<Tupel> optionalValues替换为Map<String,Tupel> optionalValues,其中键是Tupel#id,并将包含所有可用的Tupel#id值的List<String>属性添加到bean中,则此方法有效。
<p:columns value="#{tableOverviewBean.availableTupelIds}" var="id" headerText="#{id}">
    #{data.optionalValues[id].value}
</p:columns>

这两个解决方案都不能真正解决我的问题。我在问题中添加了一个示例输出。有没有办法得到这样的表格? - veote
是的,我已经阅读了。我的行有相同数量的列。但是如果我得到另一个数据集,列数可能会有所不同。例如,有一次有10个可选值(每个数据对象都有10个)。另一个集合可能有8个可选值。 - veote
colspan 值怎么办?如果 colspan 值适合,不同行可以有不同的元素,从而实现正确的 HTML 表格。 - opfau
@opfau:colspan 不会改变列数,它只是合并单元格。 - BalusC
我填充了我的模型,以满足每行相同的列大小。在我的情况下,所有行都有5列。在第一行中,第一列有一个元素,第二列有一个元素,它定义了一个跨度为3的colspan。但它没有跨越。 - opfau
显示剩余2条评论

1

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;
        }
    }

以及XHTML:

                <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>

这是一个例子。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接