我在编写自定义组件时遇到问题,因为它不会呈现任何嵌套控件。该组件是一个简单的布局控件,非常松散地改编自扩展库中的 ApplicationLayout 控件。 XPage 代码如下所示:
<px:exampleControl id="exampleControl1">
<xp:span styleClass="mySpan">Inner Text</xp:span>
</px:exampleControl>
exampleControl 将呈现良好,但嵌套跨度不会。我的基本渲染器代码是:
public class ExampleRenderer extends Renderer {
@Override
public void encodeBegin(FacesContext context, UIComponent component)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", component);
writer.writeAttribute("class", "custom-banner", null);
writer.endElement("div");
writer.startElement("div", component);
writer.writeAttribute("class", "main-body", null);
}
@Override
public boolean getRendersChildren() {
return true;
}
@Override
public void encodeChildren(FacesContext context, UIComponent component) {
try {
super.encodeChildren(context, component);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void encodeEnd(FacesContext context, UIComponent component)
throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.endElement("div");
writer.startElement("div", component);
writer.writeAttribute("class", "custom-footer", null);
writer.endElement("div");
}
}
我什至尝试使用从扩展库渲染器(AbstractApplicationLayoutRenderer.java 中的实用程序函数)借用的特定渲染函数,但 component.getChildCount() 始终返回 0。
那么为什么嵌套控件不渲染,我错过了什么?
最佳答案
我终于想通了。 Renderer 代码有点像红鲱鱼,因为正如 Stephan (stwissel) 评论的那样,Renderer.encodeChildren 什么都不做。查看几个 ExtLib 组件的来源,没有一个使用它。
我所做的更改是扩展类。在阅读了 Keith Strickland 的博客 (http://www.keithstric.com/A55BAC/keithstric.nsf/default.xsp?documentId=82770C11FA7B9B21852579C100581766) 并检查了 com.ibm.xsp.extlib.component.layout.UIVarPublisherBase 之后,我实现了 FacesComponent 接口(interface)。特别是,我想调用调用 FacesComponentBuilder 的 buildContents 方法。 FacesComponent 的 JavaDoc 对 FacesComponent 有这样的说法:
buildContents Build the component children and facets, the default implementation is usually: builder.buildAll(context, this, true); // includeFacets=true
我的扩展类最终看起来像这样:
package com.example.component;
import javax.faces.FacesException;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import com.ibm.xsp.component.FacesComponent;
import com.ibm.xsp.page.FacesComponentBuilder;
public class CustomLayout extends UIComponentBase implements FacesComponent {
public CustomLayout(){
super();
setRendererType("com.example.applicationlayout");
}
@Override
public String getFamily() {
return "com.example.applicationlayout";
}
public void buildContents(FacesContext context, FacesComponentBuilder builder)
throws FacesException {
builder.buildAll(context, this, true);
}
public void initAfterContents(FacesContext context) throws FacesException {
}
public void initBeforeContents(FacesContext context) throws FacesException
}
}
它现在似乎可以按我的意愿工作。
顺便说一句,ExtLib 中的其他对象(特别是 UIWidgetContainer 和 UIList)在不实现 FacesComponent 的情况下具有不同的渲染子对象的方式。这可能需要一篇博文。
关于jsf - 自定义组件不会显示嵌套组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23389209/