简体   繁体   English

如何在f:selectItems中为枚举创建和使用通用bean?

[英]How to create and use a generic bean for enums in f:selectItems?

I have generic class with this signature: 我有这个签名的泛型类:

public abstract class EnumListBean<E extends Enum<E>> {

    public List<E> getEnumList() {
        //implementation details
    }

}

Currently I have to define a empty subclass in order to access the enumList property for a concrete generic parameter: 目前,我必须定义一个空子类,以便访问具体泛型参数的enumList属性:

@ManagedBean
@ApplicationScoped
public class ItemRarityBean  extends EnumListBean<Item.Rarity>{
}

This makes its possible to access the property eg: 这使得访问该属性成为可能,例如:

<f:selectItems value="#{itemRarityBean.enumList}" var="rarity"
            itemLabel="#{rarity.readableName}" itemValue="#{rarity}" />

Im wondering whether one really have to declare a deriving bean but cant access the generic class as bean directly: 我想知道是否真的必须声明一个派生bean但不能直接访问泛型类作为bean:

<f:selectItems value="#{enumListBean<Item.Rarity>.enumList}" var="rarity"
                itemLabel="#{rarity.readableName}" itemValue="#{rarity}" />

You can't use generics in EL. 你不能在EL中使用泛型。 EL is a runtime language based on reflection. EL是一种基于反射的运行时语言。 You know, generics is only available during compiletime, not during runtime. 您知道,泛型仅在编译期间可用,而不是在运行时期间。

For your particular purpose, it's likely easier to use OmniFaces <o:importConstants> . 出于特定目的,使用OmniFaces <o:importConstants>可能更容易。

<o:importConstants type="com.example.Item$Rarity" var="Rarity" />
...
<h:selectOneMenu>
    <f:selectItems value="#{Rarity}" />
</h:selectOneMenu>

(the var attribute is not mandatory, but you'd otherwise need to reference it as #{Item$Rarity} which is not exactly nicely readable; if your Rarity enum were a standalone enum and not an inner enum, then you could just use type="com.example.Rarity" ) var属性不是必需的,但你需要引用它作为#{Item$Rarity} ,它不是很好读;如果你的Rarity枚举是一个独立的枚举而不是内部枚举,那么你可以使用type="com.example.Rarity"

It's by design treated as a Map<String, Rarity> , not a List<Rarity> or so. 它的设计被视为Map<String, Rarity> ,而不是List<Rarity>左右。 So if you intend to access the individual items in the var attribute of <f:selectItems> , so that you can access specific enum methods, then you'd need to explicitly iterate over Map#values() (which would require EL 2.2 support). 因此,如果您打算访问<f:selectItems>var属性中的各个项目,以便可以访问特定的枚举方法,那么您需要显式迭代Map#values() (这需要EL 2.2支持) )。

<h:selectOneMenu>
    <f:selectItems value="#{Rarity.values()}" var="rarity" itemValue="#{rarity}" itemLabel="#{rarity.readableName}" />
</h:selectOneMenu>

Yes, you have to. 是的,你必须。 Because instantiating abstract classes makes no sense. 因为实例化抽象类没有任何意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM