f : selectItem (s)에서 열거 형 값을 사용하는 방법


103

질문의 상태를 선택할 수 있도록 selectOneMenu 드롭 다운을 만들고 싶습니다. 열거 형의 순서가 변경되고 목록이 큰 경우 어떻게되는지 고려하여 f : selectItem을 더 유연하게 만들 수 있습니까? 더 잘 할 수 있을까요? 질문에있는 항목을 자동으로 "선택"할 수 있습니까?

Enum 클래스

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>

답변:


210

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>하는 T[]List<T>잘으로 인정하고 있고하여 현재 항목에 액세스 할 수 var속성)

JSF 유틸리티 라이브러리 OmniFaces 를 사용 <o:importConstants>하면 빈 대신 사용할 수 있습니다 .

<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

BalusC의 한 가지는 질문이 기본으로있는 상태를 "선택"/보기 할 수 있다는 것입니다 (예를 들어 질문을 편집 할 때 이미 질문의 상태를 무언가로 설정했습니다)
LuckyLuke

위의 예에서 JSF는 #{bean.question.status}유효한 enum 값이 있을 때 기본적으로이를 수행합니다 . question에 적절한 상태 속성이 미리 채워져 있는지 확인하기 위해 아무것도 할 필요가 없습니다 .
BalusC 2011

@BalusC JSF에서 서수 값에 액세스하는 방법은 무엇입니까?
jacktrades

2
나처럼에 대한 숫자 형식 예외가 발생 하면 @Ziletka가 제안한대로 += status사용해보십시오 .concat(status).
whistling_marmot 2016 년

java.util.List를 선호하는 경우 getStatuses () 반환 유형을 List <Status>로 수정하고 Arrays.asList (Status.values ​​());
stakahop

16

현지화를 위해 다음 솔루션도 사용할 수 있습니다.

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>

따라서 현지화 문자열의 리소스 경로는 Enum에서 하드 코딩되지 않습니다.


1
이 구문은 "상대적으로"새로운 EL 2.2 이후에만 지원됩니다. 그렇지 않으면 당신은 항상 잡아 수 있습니다 <c:set>하거나 <ui:param>또는 사용자 정의 EL 기능을 사제.
BalusC 2012

BalusC 감사합니다. backing bean (예 : value = "# {org.myproject.Status.values}")을 사용하지 않고 어떻게 든 # {data.statuses}를 enum Class로 대체 할 수 있습니까?
Ziletka 2012

@BalusC 확실합니까? GF 3.1.2 (Mojarra JSF 2.1.6)를 사용하고 있습니다.
Ziletka 2012

4

열거 형을 래핑하는 인스턴스 <f:selectItems value="#{carBean.carList}" />목록을 사용 하고 반환 할 수 있습니다 SelectItem( Status.values()가능한 모든 값을 가져 오는 데 사용 ).


2

다음 유틸리티 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;
    }
}

taglib 파일에 el 함수로 등록하십시오.

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


#{myBundle[enumName.i18nKey]}i18n 키를 사용 하고 속성으로 열거 형에 넣을 수있는 경우 "함수"(추가 메서드)가 필요하지 않습니다 . BLA_TYPE("SOME_BLA_TYPE_KEY")by BLA_TYPE는 사용할 열거 형이고 SOME_BLA_TYPE_KEYi18n 키입니다.
Roland
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.