【问题标题】:Rules for checking rendered-attribute for JSF2 custom-component检查 JSF2 自定义组件的渲染属性的规则
【发布时间】:2013-08-11 08:45:39
【问题描述】:

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

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

当然,我可以在这两种方法中检查属性 rendered,添加 @Override public boolean getRendersChildren() 并检查 rendered 属性,然后简单地不渲染子项encodeChildren.

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

【问题讨论】:

    标签: jsf-2 custom-component rendered-attribute


    【解决方案1】:

    UIComponent class 的 javadoc 中已经对此进行了描述。

    encodeBegin() method为例:

    编码开始

    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() method:

    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,则渲染这个UIComponent 的子UIComponents。仅当rendersChildren 属性为true 时才会调用此方法。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      • 1970-01-01
      • 2020-04-06
      • 1970-01-01
      • 2016-01-18
      • 2020-03-01
      • 2019-09-25
      相关资源
      最近更新 更多