Использование java.util.Map в h: dataTable
Мне нужно отобразить Map
с помощью <h:dataTable>
. Моя поддержка bean имеет свойство Map
, как показано ниже:
public class Bean {
private Map<Integer,String> map; // +getter
@PostConstruct
public void init() {
map = new TreeMap<Integer,String>();
map.put(1,"Sasi");
map.put(2,"Pushparaju");
map.put(3,"Venkat Raman");
map.put(3,"Prabhakaran");
}
}
Затем на странице JSF я пытаюсь связать это свойство Map
с атрибутом value
<h:dataTable>
.
<h:dataTable border="1" value="#{bean.map}" var="map">
<h:column id="column1">
<f:facet name="header">
<h:outputText value="UserId"></h:outputText>
</f:facet>
<h:outputText value="#{map.getKey}"></h:outputText>
</h:column>
<h:column id="column2">
<f:facet name="header">
<h:outputText value="Email Id"></h:outputText>
</f:facet>
<h:outputText value="#{map.getValue}"></h:outputText>
</h:column>
</h:dataTable>
Он дает en error, что getKey
и getValue
нет. Я могу понять, что это не правильный способ сделать это. Как я могу представить Map
с помощью <h:dataTable>
?
Ответы
Ответ 1
До предстоящих JSF 2.3 компоненты UIData
, такие как <h:dataTable>
, <p:dataTable>
и т.д. и <ui:repeat>
, поддерживают не итерацию по Map
. Это поддерживается только в <c:forEach>
.
Один из способов - преобразовать записи в массив в массив (один entrySet()
не будет работать, поскольку UIData
также не поддерживает Set
до предстоящего JSF 2.3).
<h:dataTable value="#{bean.map.entrySet().toArray()}" var="entry">
<h:column>#{entry.key}</h:column>
<h:column>#{entry.value}</h:column>
</h:dataTable>
Другой способ заключается в том, чтобы обернуть набор записей карты в коллекцию, которую может выполнять итерация <h:dataTable>
, например ArrayList
.
public class Bean {
private Map<Integer, String> map;
private List<Entry<Integer, String>> entries; // +getter (no setter necessary)
@PostConstruct
public void init() {
map = new TreeMap<>();
map.put(1, "Sasi");
map.put(2, "Pushparaju");
map.put(3, "Venkat Raman");
map.put(4, "Prabhakaran");
entries = new ArrayList<>(map.entrySet());
}
// ...
}
<h:dataTable value="#{bean.entries}" var="entry">
<h:column>#{entry.key}</h:column>
<h:column>#{entry.value}</h:column>
</h:dataTable>
Однако более чистое, самодокументируемое и многоразовое использование заключается в использовании List<User>
вместо этого, в котором класс User
обладает необходимыми свойствами id
и name
.
public class Bean {
private List<User> users; // +getter (no setter necessary)
@PostConstruct
public void init() {
users = new ArrayList<>();
users.add(new User(1, "Sasi"));
users.add(new User(2, "Pushparaju"));
users.add(new User(3, "Venkat Raman"));
users.add(new User(4, "Prabhakaran"));
}
// ...
}
<h:dataTable value="#{bean.users}" var="user">
<h:column>#{user.id}</h:column>
<h:column>#{user.name}</h:column>
</h:dataTable>
Ответ 2
Вы также можете попробовать эту альтернативу.
<h:dataTable border="1" value="#{myBean.map.keySet().toArray()}" var="myVar">
<h:column id="column1">
<f:facet name="header">
<h:outputText value="UserId"></h:outputText>
</f:facet>
<h:outputText value="#{myVar}"></h:outputText>
</h:column>
<h:column id="column2">
<f:facet name="header">
<h:outputText value="Email Id"></h:outputText>
</f:facet>
<h:outputText value="#{myBean.map.get(myVar)}"></h:outputText>
</h:column>
</h:dataTable>
Ответ 3
Что касается последнего ответа от prageeth, вы можете использовать entrySet вместо keySet; то вы можете избавиться от myBean.map.get. См. Этот пример:
<h:dataTable border="1" value="#{myBean.map.entrySet().toArray()}" var="map">
<h:column id="column1">
<f:facet name="header">
<h:outputText value="UserId"></h:outputText>
</f:facet>
<h:outputText value="#{map.key}"></h:outputText>
</h:column>
<h:column id="column2">
<f:facet name="header">
<h:outputText value="Email Id"></h:outputText>
</f:facet>
<h:outputText value="#{map.value}"></h:outputText>
</h:column>
</h:dataTable>
Это работает на myfaces 2.2.3, поскольку я только что использовал его сам.
Аннотация: Я бы лучше прокомментировал последнее сообщение, но моя репутация недостаточно высока, поэтому это дополнительный ответ.