好的,标题有点混乱,但我不知道如何用一句话来解决我的问题。
所以这是交易:我需要在 MenuItem 组件中以某种方式从 Primefaces(或者更好的是 Omnifaces,因为我从数据库加载图像并且我已经在应用程序中使用 o:graphicImage)实现 graphicsImage 组件,以便在 MegaMenu 组件中显示它使用在支持 bean 中创建的 DefaultMenuModel 以编程方式创建。另外(正如我上面提到的),图像是从数据库加载的,所以我想通过 css 加载这些图像(图标)的解决方案不适用,因为图像是动态的。
我尝试了很多方法,但(不用说)不幸的是,我失败了:-(。我没有任何编写全栈 Primefaces 自定义组件的经验,所以我尝试了一些基本的 MegaMenu 组件自定义渲染器。例如,我试过使用来自 o:graphicImage 组件(encodeBegin 和 encodeEnd)的代码并在我的 CustomMegaMenuRenderer(它扩展了 MegaMenuRenderer)中的重写方法 encodeMenuItemContent 中实现它。我使用小技巧来传递 EL 表达式(如 #{imageStreamer.getImage(23)},其中23 是实际图像 ID)将此字符串作为模型中 MenuItem 组件的“图标”字段的值传递。然后,在覆盖的 encodeMenuItemContent 中,我检查它是否实际上是 el(而不是图标名称),我执行以下操作:
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) 无法像在通常装箱的 o:graphicImage 组件中那样返回字符串内容。
我还尝试了其他一些方法,例如在渲染中以编程方式实例化graphicImage组件(来自Primefaces或Omnifaces),然后在对象上调用encodeAll方法,但这也失败了......
GraphicImage gi = (GraphicImage) application.createComponent(GraphicImage.COMPONENT_TYPE);
gi.getAttributes().put("value", expression);
gi.encodeAll(context);
所以我得出结论,我在那里错过了一些非常大的东西。我试图在 SO 和 google 上找到类似的东西,但未能成功。所以,这里是我真正的问题(假设我的方法很糟糕):
- 是否可以在自定义渲染器中实例化每个 primefaces/omnifaces 组件并使其像正常工作一样工作(所以它按预期呈现自己)?我想这将是让我的渲染器按需要工作的最简单方法......
- 我应该继续使用这种“自定义渲染器”方法还是在这种情况下没用?
- 我是否必须制作自定义 MenuModel、MenuItem 或 MegaMenu 类才能创建上述功能?
- 最后,什么是理论上最简单的实现方式,什么是实现这个的“最佳”方式(因此它与 primefaces 组件设计相一致,实际上“应该”如何完成)?
还要提一下(但我猜它超出了范围),我在 Tomcat 8 上使用 JSF MOJARRA 2.2.9、Primefaces 5.1、Omnifaces 2.0 和 Weld。
提前致谢。