Как использовать значения перечисления в 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)