jsf - 自定义组件不会显示嵌套组件

标签 jsf xpages custom-component

我在编写自定义组件时遇到问题,因为它不会呈现任何嵌套控件。该组件是一个简单的布局控件,非常松散地改编自扩展库中的 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/

相关文章:

java - Bluemix 和 Java Server Faces

java - Primefaces 数据表过滤器

Xpages 从 Lotus 获取邮件文件

android - 为 <declare-stylable> 定义一个必需的属性

javascript - 通过 Javascript 单击时 PrimeFaces 单选按钮样式不更新

xpages - 为多个应用程序创建统一的应用程序布局

javascript - .焦点不固定

javascript - 如何在页面加载后将焦点设置到 good.ui.Component 或 goog.uiControl 子类组件?

android - 复合布局是否总是需要自己的类?

java - MVC 和 JavaServer Faces