【问题标题】:How to create Primefaces radioButtons from List?如何从列表创建 Primefaces 单选按钮?
【发布时间】:2012-10-29 20:21:01
【问题描述】:

我想从对象列表#{item.items3} 创建一组单选按钮并将所选对象存储到#{cartBean.selectedChoice}。现在我真的不明白<f:selectItems><ui:repeat> 所需的值之间的区别。我的代码看起来如何。到目前为止有什么明显的错误吗?

<p:selectOneRadio id="myRadio" value="#{cartBean.selectedChoice}" layout="custom">
    <f:selectItems value="#{item.items3}"/>
</p:selectOneRadio>

<h:panelGrid columns="1">
    <ui:repeat var="choice" value="#{item.items3}" varStatus="choiceIndex">
        <p:radioButton id="choiceRadio" for=":iterateCategories:iterateItems:lightForm:myRadio" itemIndex="#{choiceIndex.index}" />#{choice.name}
    </ui:repeat>
</h:panelGrid>

目前我收到以下错误:

20:58:52,397 信息 [javax.enterprise.resource.webcontainer.jsf.renderkit] (http-localhost-127.0.0.1-8080-1) 警告:FacesMessage(s) 已 已入队,但可能尚未显示。 sourceId=iterateCategories:0:iterateItems:2:lightForm:myRadio[severity=(ERROR 2)、summary=(Conversion Error设置值 'huhu.model.generated.Item@3ae5e1dc' 用于'空转换器'。), detail=(转换错误设置值 'huhu.model.generated.Item@3ae5e1dc' for 'null Converter'。)]

我不明白,哪里可能存在转换问题,因为只处理同一类的对象。

【问题讨论】:

    标签: jsf-2 primefaces radio-button


    【解决方案1】:

    JSF 生成 HTML。 HTML 基本上是一个大字符串。因此,非字符串类型的 Java 对象需要转换为字符串。如果遇到没有内置转换器(NumberBooleanEnum)或自定义转换器(实现 Converter 的类)的类型,则将使用对象的默认 toString() 实现将复杂的 Java 对象打印到 HTML 输出中。如果您的对象没有重写此方法,那么它将是Object#toString() 的默认实现,在javadoc 中进行了描述:

    Object 类的 toString 方法返回一个字符串,该字符串由对象作为其实例的类的名称、@ 符号字符和对象哈希码的无符号十六进制表示组成.换句话说,这个方法返回一个字符串等于:

    getClass().getName() + '@' + Integer.toHexString(hashCode())
    

    在您的特定情况下,生成的 HTML 单选按钮元素如下:

    <input type="radio" ... value="huhu.model.generated.Item@3ae5e1dc" />
    

    (在浏览器中右键单击页面并选择查看源代码自己查看)

    现在,当提交此表单时,request.getParameter() 收集的输入值huhu.model.generated.Item@3ae5e1dc(返回String!)必须转换回您的自定义类型Item 的具体实例。但是,由于自定义类型显然没有注册转换器(错误消息已经提示:“null converter”),JSF 无法将其转换回Item,并将抛出此转换器异常。

    您确实应该提供一个自定义转换器,该转换器可以在 Item 与其独特的 String 表示之间正确转换。技术 ID(例如从数据库中自动生成的 PK)经常被用作唯一的 String 表示。转换器将如下所示:

    @FacesConverter(forClass=Item.class)
    public class ItemConverter implements Converter {
    
        @Override
        public void getAsString(FacesContext context, UIComponent component, Object modelValue) throws ConverterException {
            // Write code to convert Item to its unique String representation. E.g.
            return String.valueOf(((Item) modelValue).getId());
        }
    
        @Override 
        public void getAsObject(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
            // Write code to convert unique String representation of Item to concrete Item. E.g.
            return someItemService.find(Long.valueOf(submittedValue));
        }
        
    }
    

    或者,您可以使用 JSF 实用程序库 OmniFacesSelectItemsConverter,以便转换器将使用 &lt;f:selectItem(s)&gt; 作为转换基础。这样您就不需要为您想在&lt;f:selectItem(s)&gt; 中使用的每个自定义 Java 类型创建自定义转换器。另见the SelectItemsConverter showcase page

    <p:selectOneRadio ... converter="omnifaces.SelectItemsConverter">
    

    【讨论】:

    • 感谢您提供自行设置转换器所需信息的详细回答。由于我不确定,我可能需要转换什么其他 Java 类型,所以我选择了 omnifaces 替代方法来处理转换问题。
    • 我仍然不明白&lt;f:selectItems&gt;&lt;ui:repeat&gt; 的值之间的差异。 &lt;ui:repeat&gt; 有必要吗?
    • &lt;ui:repeat&gt; 是必要的,因为您使用了layout="custom"(您基本上是在指定您希望您自己而不是依赖于默认演示文稿)。如果你去掉layout="custom",那确实没必要。
    • 这绝对是有道理的。但是我从哪里获得itemIndex-attribute for &lt;p:radioButton&gt; 的值?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    • 2011-10-21
    • 2011-01-01
    • 1970-01-01
    相关资源
    最近更新 更多