Как использовать значения перечисления в f: selectItem(s)
Я хочу сделать выпадающий список selectOneMenu, чтобы я мог выбрать статус по моему вопросу. Можно ли сделать f:selectItem более гибким, учитывая, что произойдет, если порядок перечислений изменится, и если список был большим? И могу ли я сделать это лучше? И можно ли автоматически "выбрать" элемент, который есть в вопросе?
перечислимый класс
public enum Status {
SUBMITTED,
REJECTED,
APPROVED
}
вопрос сущность
@Enumerated(EnumType.STRING)
private Status status;
JSF
<div class="field">
<h:outputLabel for="questionStatus" value="Status" />
<h:selectOneMenu id="questionStatus" value="#{bean.question.status}" >
<f:selectItem itemLabel="Submitted" itemValue="0" />
<f:selectItem itemLabel="Rejected" itemValue="1" />
<f:selectItem itemLabel="Approved" itemValue="2" />
</h:selectOneMenu>
<hr />
</div>
4 ответа:
JSF имеет встроенный конвертер для
enum
, так это:@ManagedBean @ApplicationScoped public class Data { public Status[] getStatuses() { return Status.values(); } }
С
<h:selectOneMenu value="#{bean.question.status}" > <f:selectItems value="#{data.statuses}" /> </h:selectOneMenu>
(Примечание: начиная с версии JSF 2.0 нет никакой необходимости, чтобы обеспечить
SelectItem[]
илиList<SelectItem>
, aT[]
иList<T>
принимаются также и вы можете получить доступ к текущему пункту )если вы случайно используете JSF utility library OmniFaces, тогда вы могли бы использовать
<o:importConstants>
вместо a фасоль.<o:importConstants type="com.example.Status" /> <h:selectOneMenu value="#{bean.question.status}" > <f:selectItems value="#{Status}" /> </h:selectOneMenu>
если вы также собираетесь контролировать метки, Вы можете добавить их в
Status
перечисление:public enum Status { SUBMITTED("Submitted"), REJECTED("Rejected"), APPROVED("Approved"); private String label; private Status(String label) { this.label = label; } public String getLabel() { return label; } }
С
<f:selectItems value="#{data.statuses}" var="status" itemValue="#{status}" itemLabel="#{status.label}" />
или, лучше, сделайте значение enum ключом свойства локализованного пакета ресурсов (требуется EL 3.0):
<f:selectItems value="#{data.statuses}" var="status" itemValue="#{status}" itemLabel="#{text['data.status.' += status]}" />
с этим в файле свойств, связанном с пакетом ресурсов
#{text}
data.status.SUBMITTED = Submitted data.status.REJECTED = Rejected data.status.APPROVED = Approved
для локализации мы можем использовать также это решение:
public enum Status { SUBMITTED, REJECTED, APPROVED } data.status.SUBMITTED=Submitted data.status.REJECTED=Rejected data.status.APPROVED=Approved <h:selectOneMenu value="#{bean.question.status}" > <f:selectItems value="#{data.statuses}" var="status" itemValue="#{status}" itemLabel="#{text['data.status.'.concat(status)]}" /> </h:selectOneMenu>
таким образом, путь к ресурсу для строк локализации не жестко закодирован в перечислении.
вы могли бы использовать
<f:selectItems value="#{carBean.carList}" />
и вернуть списокSelectItem
экземпляры, которые обертывают перечисление (использоватьStatus.values()
чтобы получить все возможные значения).
вы можете использовать следующую функцию утилиты el для получения значений перечисления и использовать их в
SelectOneMenu
например. Нет необходимости создавать бобы и шаблонные методы.public final class ElEnumUtils { private ElEnumUtils() { } /** * Cached Enumerations, key equals full class name of an enum */ private final static Map<String, Enum<?>[]> ENTITY_ENUMS = new HashMap<>();; /** * Retrieves all Enumerations of the given Enumeration defined by the * given class name. * * @param enumClassName Class name of the given Enum. * * @return * * @throws ClassNotFoundException */ @SuppressWarnings("unchecked") public static Enum<?>[] getEnumValues(final String enumClassName) throws ClassNotFoundException { // check if already cached - use classname as key for performance reason if (ElEnumUtils.ENTITY_ENUMS.containsKey(enumClassName)) return ElEnumUtils.ENTITY_ENUMS.get(enumClassName); final Class<Enum<?>> enumClass = (Class<Enum<?>>) Class.forName(enumClassName); final Enum<?>[] enumConstants = enumClass.getEnumConstants(); // add to cache ElEnumUtils.ENTITY_ENUMS.put(enumClassName, enumConstants); return enumConstants; } }
зарегистрировать его в качестве функции Эл в файле библиотеки тегов:
<function> <description>Retrieves all Enumerations of the given Enumeration defined by the given class name.</description> <function-name>getEnumValues</function-name> <function-class> package.ElEnumUtils </function-class> <function-signature> java.lang.Enum[] getEnumValues(java.lang.String) </function-signature> </function>
и, наконец, назовите его так:
<p:selectOneMenu value="#{bean.type}"> <f:selectItems value="#{el:getEnumValues('package.BeanType')}" var="varEnum" itemLabel="#{el:getEnumLabel(varEnum)}" itemValue="#{varEnum}"/> </p:selectOneMenu>
аналогично ответу BalusC вы должны использовать пакет ресурсов с локализованными метками перечисления, а для более чистого кода Вы также можете создать такую функцию, как
getEnumLabel(enum)