च में एनम मूल्यों का उपयोग कैसे करें: selectItem (s)


103

मैं एक SelectOneMenu ड्रॉपडाउन बनाना चाहता हूं ताकि मैं अपने प्रश्न पर एक स्थिति का चयन कर सकूं। क्या यह संभव है कि f: चयन करें और अधिक लचीला यह देखते हुए कि क्या होता है अगर एनम का क्रम बदलता है, और यदि सूची बड़ी थी? और क्या मैं इसे बेहतर कर सकता था? और क्या उस आइटम का स्वचालित रूप से "चयन" करना संभव है जो सवाल है?

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>

यदि आप लेबल को नियंत्रित करने का इरादा रखते हैं, तो आप उन्हें Statusenum में जोड़ सकते हैं :

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}" />

या, बेहतर, एनम वैल्यू को स्थानीयकृत संसाधन बंडल (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

एक बात बालूसी, क्या यह संभव है कि "चयन करें" / उस स्थिति को देखें जो एक प्रश्न के रूप में डिफ़ॉल्ट है (उदाहरण के लिए जब आप एक प्रश्न को संपादित कर रहे हैं तो आप पहले से ही प्रश्न की स्थिति को कुछ सेट कर चुके हैं)
LuckyLuke

उपरोक्त उदाहरण में, जेएसएफ डिफ़ॉल्ट रूप से तब करेगा जब #{bean.question.status}उसके पास वैध एनम मूल्य होगा। आपको यह सुनिश्चित करने के लिए कुछ भी करने की आवश्यकता नहीं है कि questionउचित स्थिति की संपत्ति पूर्वनिर्मित है।
बालुसक

@BalusC JSF से क्रमिक मूल्य तक कैसे पहुँचें?
कटक

2
यदि, मेरी तरह, आपको इसके लिए एक नंबर प्रारूप अपवाद मिलता है += status, तो उपयोग करने का प्रयास करें.concat(status) @Ziletka के रूप में ।
सीटी

यदि आप java.util पसंद करते हैं। आप केवल getStatuses () प्रकार को सूची <स्थिति> में लौटा सकते हैं और Arrays.asList (Status.values ​​()) वापस कर सकते हैं;
स्टाकहॉप

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>या एक कस्टम ईएल समारोह homebrew।
बालुस

धन्यवाद BalusC क्या बैकिंग बीन (जैसे मान = "# {org.myproject.Status.values}") का उपयोग किए बिना, एनम वर्ग के साथ किसी तरह # {data.statuses} को बदलना संभव है?
sasynkamil

@BalusC क्या आपको यकीन है? मैं GF 3.1.2 का उपयोग कर रहा हूं (मोजरा JSF 2.1.6)।
sasynkamil

4

आप उन उदाहरणों की <f:selectItems value="#{carBean.carList}" />सूची का उपयोग कर सकते हैं और वापस कर सकते हैं SelectItemजो एनम को लपेटते हैं ( Status.values()सभी संभावित मूल्यों को प्राप्त करने के लिए उपयोग करें)।


2

आप एनम वैल्यू प्राप्त करने के लिए यूटिलिटी एल फंक्शन का उपयोग कर सकते हैं और 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)


एक "फ़ंक्शन" (विधि अधिक) के लिए कोई ज़रूरत नहीं है, जब आप उपयोग कर सकते हैं #{myBundle[enumName.i18nKey]}और फिर गुण के रूप में i18n कुंजियों को अपनी गणना में डाल सकते हैं : BLA_TYPE("SOME_BLA_TYPE_KEY")द्वारा उपयोग BLA_TYPEकी जाने वाली Enum SOME_BLA_TYPE_KEYहै और i18n कुंजी है।
रोलैंड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.