2

我有一个像这样的简单自定义组件,它不尊重呈现的属性。

@FacesComponent("my.OutputText")
public class OutputText extends UIPanel
{   
  @Override public void encodeBegin(FacesContext context) throws IOException {...}
  @Override public void encodeEnd(FacesContext context) throws IOException {...}
}

当然,我可以检查两种方法中呈现的属性,添加@Override public boolean getRendersChildren()并检查呈现的属性,然后简单地不在encodeChildren.

但是实现这个通用特性的推荐规则是什么?

4

1 回答 1

1

这已经在UIComponentclass的 javadoc 中进行了描述。

encodeBegin()方法为例:

编码开始

public abstract void encodeBegin(FacesContext context)
                     throws java.io.IOException

如果我们的rendered属性是true,则将 this 的当前状态的开始呈现UIComponent给包含在指定 FacesContext 中的响应。打电话pushComponentToEL(javax.faces.context.FacesContext,javax.faces.component.UIComponent)。调用Application.publishEvent(javax.faces.context.FacesContext, java.lang.Class, java.lang.Object),作为第一个参数传递,要呈现的组件实例作为第二个参数传递。PreRenderComponentEvent.class

如果 aRenderer与 this 相关联UIComponent,则实际编码将委托给Renderer#encodeBegin(FacesContext, UIComponent).

如果我们渲染的属性是false,立即调用pushComponentToEL(javax.faces.context.FacesContext,javax.faces.component.UIComponent)并返回。

getRendersChildren()方法

getRendersChildren

public abstract boolean getRendersChildren()

返回一个标志,指示此组件是否负责渲染其子组件。中的默认实现UIComponentBase#getRendersChildren尝试查找此组件的渲染器。如果是,它调用Renderer#getRendersChildren并返回结果。如果没有,则返回false. 从 JavaServer Faces 规范 1.2 版开始,鼓励组件作者true从此方法返回并依赖UIComponentBase#encodeChildren.

注意最后一条语句。这是一个UIComponent#encodeChildren()

编码儿童

public abstract void encodeChildren(FacesContext context)
                         throws java.io.IOException

如果我们的rendered属性是true,则渲染UIComponentsthis的子级UIComponentrendersChildren仅当属性为时才会调用此方法true

如果 aRenderer与 this 相关联UIComponent,则实际编码将委托给Renderer#encodeChildren(FacesContext, UIComponent). 如果 noRenderer与此关联UIComponent,则遍历此组件的每个子组件并调用encodeAll(javax.faces.context.FacesContext).

请注意,UIComponentBase它们已经实施。如果您覆盖了一个方法,那么您需要遵循完全相同的规则,或者super.encodeXxx()尽可能使用。如果您没有encodeChildren()覆盖,那么无论如何您都不需要这样做。

于 2013-08-11T11:14:42.387 回答