好吧,标题有点令人困惑,但我无法弄清楚如何用单句来解决我的问题。
所以这是交易: 我需要以某种方式实现Primefaces中的graphicImage组件(甚至更好,Omnifaces,因为我从数据库加载图像,我已经在应用程序中使用o:graphicImage)在MenuItem组件中,以便在MegaMenu组件中显示它,该组件是使用创建的DefaultMenuModel以编程方式创建的在支持豆。另外(如上所述),图像是从数据库加载的,所以我想通过css加载这些图像(图标)的解决方案不适用,因为图像是动态的。
我尝试了很多方法但是(不用说)我很遗憾地失败了:-(。我没有任何编写完整堆栈Primefaces自定义组件的经验,因此我尝试使用MegaMenu组件的一些基本自定义渲染器。例如,我试图使用来自o:graphicImage组件(encodeBegin和encodeEnd)的代码,并在我的CustomMegaMenuRenderer(它扩展MegaMenuRenderer)中实现它在重写方法encodeMenuItemContent。我使用小hack传递EL表达式(如#{imageStreamer.getImage(23) },其中23是实际图像id)将此字符串作为模型中MenuItem组件的'icon'字段的值传递。然后,在重写的encodeMenuItemContent中,我检查它是否实际上是el(而不是图标名称)我做这样的事情:< / p>
writer.startElement("img", null);
writer.writeURIAttribute("src", getSrc(context, expresion), "value");
writeAttributes(writer, this, GraphicImage.ATTRIBUTE_NAMES);
writer.endElement("img");
其中getSrc(context,expression)的实现方式如下:
private String getSrc(FacesContext context, String expression) throws IOException {
Resource resource;
ExpressionFactory ef = context.getApplication().getExpressionFactory();
ValueExpression dynExpression = ef.createValueExpression(context.getELContext(), expression, Object.class);
resource = GraphicResource.create(context, dynExpression, null);
return context.getExternalContext().encodeResourceURL(resource.getRequestPath());
}
但不幸的是,getSrc(context,expression)无法返回字符串内容,就像它在正常crated o:graphicImage组件中一样。
我还尝试了一些其他的方法,比如在我的渲染中以编程方式实例化graphicImage组件(来自Primefaces或Omnifaces),然后在对象上调用encodeAll方法但是也失败了......
GraphicImage gi = (GraphicImage) application.createComponent(GraphicImage.COMPONENT_TYPE);
gi.getAttributes().put("value", expression);
gi.encodeAll(context);
所以我得出结论,我错过了一些非常重要的东西。我试图在SO和谷歌上找到类似的东西,但无法成功。所以,这里是我真正的问题(假设我的方法很糟糕):
另外要提一下(但我猜它超出了范围),我在Tomcat 8上使用JSF MOJARRA 2.2.9,Primefaces 5.1,Omnifaces 2.0和Weld。
提前致谢。
答案 0 :(得分:0)
据我了解,你试图使用类似的东西:
<p:menuitem ... icon="#{imageStreamer.getImage(23)}" />
这确实行不通。当渲染器获得它时,将立即对其进行评估。这也不是<o:graphicImage>
的工作原理。它将评估推迟到浏览器实际需要请求图像的那一刻。
您最好的选择是传递图像标识符:
<p:menuitem ... icon="23" />
(可安全地表达为icon="#{bean.iconId}"
)
然后你可以按如下方式渲染它:
@Override
protected void encodeMenuItemContent(FacesContext context, AbstractMenu menu, MenuItem menuitem) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String imageId = menuitem.getIcon();
Object value = menuitem.getValue();
if (imageId != null) {
ValueExpression expression = Components.createValueExpression("#{imageStreamer.getImage(" + imageId + ")}", Object.class);
GraphicResource resource = GraphicResource.create(context, expression, null);
String src = context.getExternalContext().encodeResourceURL(resource.getRequestPath());
writer.startElement("img", null);
writer.writeURIAttribute("src", src, null);
writer.endElement("img");
}
// ...
}
(你非常接近,唯一不幸的是你没有展示你是如何创建的expression
以及它究竟是如何失败的,因此确切的原因可以被精确定位)