Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf p:selectOneMenu不';t通过列表上的p:列呈现自定义内容<;字符串>;_Jsf_Jsf 2_Primefaces_Selectonemenu - Fatal编程技术网

Jsf p:selectOneMenu不';t通过列表上的p:列呈现自定义内容<;字符串>;

Jsf p:selectOneMenu不';t通过列表上的p:列呈现自定义内容<;字符串>;,jsf,jsf-2,primefaces,selectonemenu,Jsf,Jsf 2,Primefaces,Selectonemenu,我正在尝试使用Primefaces 5.2 SelectOne菜单来显示图像及其文件名。这就是我的xhtml当前的样子: <h:form> <h:panelGrid id="createPanelGrid" columns="2"> <p:outputLabel value="Service Logo:" /> <p:selectOneMenu value="#{imageBean.selectedImage}" var="l">

我正在尝试使用Primefaces 5.2 SelectOne菜单来显示图像及其文件名。这就是我的xhtml当前的样子:

<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>
然而,这些图片并没有呈现在网页上,只有文件名(我会发布一个截图,但我没有足够的声誉)。我没有得到两列(首先是图像,然后是文件名),我只得到文件名本身

当我将文件名字符串包装到POJO中并使用转换器时,它可以工作,但对于字符串就不行了


如何使其仅用于字符串?

原因是Primefaces库在
selectOneMenu
组件的
var
属性中指定了一个bean,但您提供的字符串对象不是bean。因此,库根本不渲染任何列覆盖。在
var
属性中需要一个bean(包装器),在
Converter
属性中需要相应的转换器。

原因是Primefaces库在
selectOneMenu
组件的
var
属性中指定了一个bean,但您给出的字符串对象不是bean。因此,库根本不渲染任何列覆盖。在
var
属性中需要一个bean(包装器),在
Converter
属性中需要相应的转换器。

这个笨拙的行为由(行号匹配5.2)确认:

因此,如果项目值是
String
的实例,则通过
的自定义内容将被完全忽略。这确实没有任何意义。直观的预期是,自定义内容通过
var
属性和/或
子项的存在进行切换。你最好向PrimeFaces的人报告一个问题来解释/改进这一点

除了提供非
字符串
类型的项值之外,解决方法是使用自定义呈现程序覆盖
SelectOneMenuRender
,该呈现程序将
字符串
包装在另一个对象中,而该对象恰好在其
toString()
中返回完全相同的值,例如
StringBuilder
。这样,渲染器将被愚弄,因为这些值不是
String
的实例。很高兴他们没有检查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);
    }

}

这种尴尬的行为通过(行号匹配5.2)得到证实:

因此,如果项目值是
String
的实例,则通过
的自定义内容将被完全忽略。这确实没有任何意义。直观的预期是,自定义内容通过
var
属性和/或
子项的存在进行切换。你最好向PrimeFaces的人报告一个问题来解释/改进这一点

除了提供非
字符串
类型的项值之外,解决方法是使用自定义呈现程序覆盖
SelectOneMenuRender
,该呈现程序将
字符串
包装在另一个对象中,而该对象恰好在其
toString()
中返回完全相同的值,例如
StringBuilder
。这样,渲染器将被愚弄,因为这些值不是
String
的实例。很高兴他们没有检查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);
    }

}


日志中没有404-当我在文件名字符串周围使用包装器类时,同样的URL也可以工作。如果我在日志中找到了可以解释的线索,我就不会发布了。对不起,我不是说日志中没有线索,只是我找不到任何线索。你能给我一个提示我在找什么(除了404,我查过了)?另外,让我感到困惑的是,在服务器端更改内容(添加包装器类)可以让它工作。不,所需的元素最终不会出现在HTML输出中,而是被忽略了。相反,我只得到文本(文件名)。如果我使用包装器类,我就可以毫无问题地得到标签。日志中没有404——当我在文件名字符串周围使用包装器类时,同样的URL也可以工作。如果我在日志中找到了可以解释的线索,我就不会发布了。对不起,我不是说日志中没有线索,只是我找不到任何线索。你能给我一个提示我在找什么(除了404,我查过了)?另外,让我感到困惑的是,在服务器端更改内容(添加包装器类)可以让它工作。不,所需的元素最终不会出现在HTML输出中,而是被忽略了。相反,我只得到文本(文件名)。如果我使用包装器类,我就可以毫无问题地得到标签。是的,这是对我有效的解决方法-我只是希望有一种更简单的方法…这就是问题所在,没有解决方法,因为没有任何解决方法。这是将图像放入Primefaces SelectOne菜单的方法。如果我的回答澄清了你的问题,请接受我的回答。要将答案标记为已接受,请单击答案旁边的复选标记,将其从空心切换为绿色。谢谢。所以字符串不是POJO?我是说bean,而不是POJO。但是它与字符串关联,而不是与对象关联,所以如果我想将对象传递给bean,我该怎么做?是的,这是对我有效的解决方法-我只是希望有一种更简单的方法…这就是问题所在,没有变通办法,因为没有变通办法。这是将图像放入Primefaces SelectOne菜单的方法。如果我的回答澄清了你的问题,请接受我的回答。要将答案标记为已接受,请单击答案旁边的复选标记,将其从空心切换为绿色。谢谢。所以字符串不是POJO?我指的是bean,而不是POJO。但它与字符串关联,而不是与对象关联,所以如果我想将对象传递给bean,我该怎么做?哇。。。非常感谢!我从来没有想过这种行为是故意的。。。再次感谢您提供了良好的解决方案!如果您有像
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            }
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);
    }

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