p:selectOneMenu不会通过List< String>上的p:column呈现自定义内容. [英] p:selectOneMenu doesn't render custom content via p:column on List<String>

查看:109
本文介绍了p:selectOneMenu不会通过List< String>上的p:column呈现自定义内容.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取Primefaces 5.2 selectOneMenu来显示图像及其文件名.这是我的xhtml当前的样子:

I'm trying to get a Primefaces 5.2 selectOneMenu to display images along with their filenames. This is what my xhtml currently looks like:

<h:form>
<h:panelGrid id="createPanelGrid" columns="2">
    <p:outputLabel value="Service Logo:" />
    <p:selectOneMenu value="#{imageBean.selectedImage}" var="l">
        <f:selectItem itemLabel="Select a logo" itemValue="" />
        <f:selectItems value="#{imageBean.imageList}" var="logo" itemLabel="#{logo}" itemValue="#{logo}" />
        <p:column>
            <p:graphicImage value="#{imageBean.imageFolder}/#{l}" style="max-width:50px;max-height:50px;" />
        </p:column>
        <p:column>#{l}</p:column>
    </p:selectOneMenu>
</h:panelGrid>

ManagedBean(imageBean)具有

The ManagedBean (imageBean) has

public List<String> getImageList () {
    List<String> imageList = new ArrayList<String>();
    File[] files = absoluteImageFolder.listFiles();
    for (File file : files) {
        imageList.add(file.getName());
    }        
    return imageList;
}

private String selectedImage;

public String getSelectedImage() {
    return selectedImage;
}

public void setSelectedImage(String selectedImage) {
    this.selectedImage = selectedImage;
}

但是,图像不会显示在网页上,而只会显示文件名(我会发布屏幕截图,但是我没有足够的声誉).我没有两列(首先是图像,然后是文件名),我只是得到文件名本身.

However, the images are not rendered on the webpage, just the filenames (I'd post a screenshot but I don't have enough reputation). I don't get two columns (first the image, then the filename), I just get the filename itself.

当我将文件名字符串包装到POJO中并使用转换器时,它可以工作-但仅使用Strings不能.

When I wrap the filename Strings into a POJO and use a converter it works - but just with Strings it doesn't.

我怎样才能使它仅与字符串一起使用?

How can I get this to work with just Strings?

推荐答案

This awkward behavior is confirmed by SelectOneMenuRenderer source code (line numbers match 5.2):

260            if(itemValue instanceof String) {
261                writer.startElement("td", null);
262                writer.writeAttribute("colspan", columns.size(), null);
263                writer.writeText(selectItem.getLabel(), null);
264                writer.endElement("td");
265            } 
266            else {
267                for(Column column : columns) {
268                    writer.startElement("td", null);
269                    renderChildren(context, column);
270                    writer.endElement("td");
271                }
272            }

因此,如果item值是String的实例,则通过<p:column>的自定义内容将被完全忽略.这确实没有任何意义.直观的期望是,通过var属性和/或<p:column>子代来切换自定义内容.您最好将问题报告给PrimeFaces的人员,以解释/改善此问题.

So, if the item value is an instance of String, custom content via <p:column> is totally ignored. This does indeed not make any sense. The intuitive expectation is that the custom content is toggled by presence of var attribute and/or <p:column> children. You'd best report an issue to PrimeFaces guys to explain/improve this.

除了提供非String类型的项目值之外,解决方法是使用自定义渲染器覆盖SelectOneMenuRenderer,该渲染器将String包装在另一个对象中,该对象恰好在其对象中返回完全相同的值. toString(),例如StringBuilder.这样,渲染器将被愚弄为值不是String的实例.很高兴他们没有检查instanceof CharSequence.

The work around, apart from providing non-String-typed item values, is to override the SelectOneMenuRenderer with a custom renderer which wraps the String in another object which happens to return exactly the same value in its toString(), such as StringBuilder. This way the renderer will be fooled that the values aren't an instance of String. Glad they didn't check for instanceof CharSequence.

public class YourSelectOneMenuRenderer extends SelectOneMenuRenderer {

    @Override
    protected void encodeOptionsAsTable(FacesContext context, SelectOneMenu menu, List<SelectItem> selectItems) throws IOException {
        List<SelectItem> wrappedSelectItems = new ArrayList<>();

        for (SelectItem selectItem : selectItems) {
            Object value = selectItem.getValue();

            if (value instanceof String) {
                value = new StringBuilder((String) value);
            }

            wrappedSelectItems.add(new SelectItem(value, selectItem.getLabel()));
        }

        super.encodeOptionsAsTable(context, menu, wrappedSelectItems);
    }

}

为了使其运行,请在faces-config.xml中将其注册如下:

In order to get it to run, register it as below in faces-config.xml:

<render-kit>
    <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.SelectOneMenuRenderer</renderer-type>
        <renderer-class>com.example.YourSelectOneMenuRenderer</renderer-class>
    </renderer>
</render-kit>

这篇关于p:selectOneMenu不会通过List&lt; String&gt;上的p:column呈现自定义内容.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆