Primefaces статические и динамические столбцы в datatable
Я использую Primefaces 5.0 для создания динамического datatable.
My DataObject имеет некоторые обязательные поля и список необязательных "tupel" (пара ключ-значение). Необязательный список может отличаться по размеру. Поэтому мне нужен динамический механизм для отображения списка DataObject в Primefaces.объект DataTable.
мой подход выглядит так:
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 ответов
невозможно определить столбцы на основе данных строк. Представьте, что строка 1 имеет 2 столбца, строка 2 имеет 6 столбцов, строка 3 имеет 1 столбец и т. д. Как бы вы создали технически допустимую таблицу в HTML? В каждой строке должно быть одинаковое количество столбцов.
у вас есть 2 варианта, в зависимости от того, можно ли изменить модель или нет:
-
если вы не можете изменить модель, то вы должны заменить
<p:columns>
один<p:column>
и петля над#{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>
-
если вы можете изменить модель, то вам нужно дать
<p:columns value>
укажите свойство bean вместо свойства строки, чтобы оно было точно таким же для каждой строки. Это работает, если вы заменитеList<Tupel> optionalValues
byMap<String, Tupel> optionalValues
где ключTupel#id
и добавитьList<String>
свойство для компонента, содержащего все доступныеTupel#id
значения.<p:columns value="#{tableOverviewBean.availableTupelIds}" var="id" headerText="#{id}"> #{data.optionalValues[id].value} </p:columns>
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>
Это пример.