我在自定义组件方面遇到问题我写的是它不会渲染任何嵌套控件。该组件是一个简单的布局控件,非常宽松地适应扩展库中的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");
}
}
我甚至尝试使用从Extension Library渲染器(AbstractApplicationLayoutRenderer.java中的实用程序函数)借用的特定渲染函数,但component.getChildCount()始终返回0.
那么为什么嵌套的控件渲染和我缺少的是什么?
答案 0 :(得分:7)
我终于弄明白了。 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接口。特别是,我想调用调用FacesComponentBuilder的buildContents方法。 JavaDoc for FacesComponent有关于FacesComponent的说法:
buildContents 构建组件子级和构面,默认实现通常是: 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。这可能需要一篇博文。