用于检查JSF2自定义组件的呈现属性的规则



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

@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(),还可以检查rendered的attribute,然后简单地不在encodeChildren中渲染子级。

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

这已经在UIComponent类的javadoc中描述过了。

encodeBegin()方法为例:

encodeBegin

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

如果我们的rendered属性是true,则将此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作为第一个参数,传递要呈现的组件实例作为第二个参数。

如果Renderer与该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()的一个:

encodeChildren

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

如果我们的rendered属性是true,则呈现此UIComponent的子UIComponents。只有当rendersChildren属性为true时,才会调用此方法。

如果Renderer与该UIComponent相关联,则实际编码将被委托给Renderer#encodeChildren(FacesContext, UIComponent)。如果没有任何Renderer与此UIComponent相关联,则遍历此组件的每个子级并调用encodeAll(javax.faces.context.FacesContext)

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

最新更新