如何将现有的 JSF 组件添加到我自己的自定义组件中?

Posted

技术标签:

【中文标题】如何将现有的 JSF 组件添加到我自己的自定义组件中?【英文标题】:How to add existing JSF components to my own custom components? 【发布时间】:2010-10-13 20:20:56 【问题描述】:

我有一个扩展 UIComponent 和 UIOutput 的标记类。在这个类中,我有 encodeBegin 和 encodeEnd ,我可以使用我的 contextWriter 输出任何我想要的 html 标签,方法是使用 writer.startElement("div", myComponent) 等等。

我现在的问题是我需要插入例如 a 而不是使用 writer.startElement。我可以通过 getChildren().add(HtmlCommandButton button = new HtmlCommandButton());但是当这样做时,我似乎无法输出我希望它们出现的组件,就像我可以使用 write.startElement 一样。

在我如何利用我自己的标签库中的richfaces 标签、JSF 标签和类似标签方面,有人有什么好的解决方案吗?简而言之,我真正想做的是在我的 encodeBegin 中:

writer.startElement("a4j:commandButton", myComponent);
writer.writeAttribite("action", "#Handler.myAction", null);
writer.endElement("a4j:commandButton");

提前致谢

【问题讨论】:

【参考方案1】:

您不能随意使用 ResponseWriter。我可以想到如何以编程方式添加子控件的两种方法是通过 binding 属性 (see this answer) 或在通常创建控件的位置(在 JSP 中,即在 tag class )。

JSF 组件有两种方式来包含其他控件:作为子控件或作为命名方面。组件总是控制它们如何渲染它们的切面;如果他们要渲染他们的孩子,他们必须为getRendersChildren返回true。

这是未经测试的代码,但顺序如下:

  @Override
  public boolean getRendersChildren() 
    return true;
  

  @Override
  public void encodeBegin(FacesContext context)
      throws IOException 
    // should really delegate to a renderer, but this is only demo code
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement("span", this);
    String styleClass = getStyleClass();
    writer
        .writeAttribute("class", styleClass, "styleClass");

    UIComponent headerComponent = getFacet("header");
    if (headerComponent != null) 
      headerComponent.encodeAll(context);
    

    writer.startElement("hr", null);
  

  @Override
  public void encodeChildren(FacesContext context)
      throws IOException 
    ResponseWriter writer = context.getResponseWriter();
    for (UIComponent kid : getChildren()) 
      kid.encodeAll(context);
      writer.startElement("br", null);
    
  

  @Override
  public void encodeEnd(FacesContext context)
      throws IOException 
    ResponseWriter writer = context.getResponseWriter();
    writer.endElement("span");
  

【讨论】:

优秀的人。我只是要测试一下。 myComponent.encodeAll(context) 正是我想要的。非常感谢!【参考方案2】:

不是真正的答案,更多的是猜测,但也许您可以扩展其中一个 facelets 控件?

或者,或者直接使用 facelets - 这似乎正是您真正想要的,尽管我自己没有使用它。或者,您可以在希望 HTML 出现的位置添加 UIOutput 控件,并将每个控件的值设置为您希望出现的 HTML - 这正是 f:verbatim 在幕后所做的,或者从查看源代码看来:- )

【讨论】:

是的,我已经在扩展 UIOutput。我不确定我会扩展什么,让我能够输出其他组件,而不仅仅是输出标签。感谢您的回复。 我查看了一些控件并编辑了问题。我没有做任何你自己用 Google 和 facets 和 facelets 资源做不到的事情! 优秀。我会尽快尝试(可能在 48 小时内,因为这两天我不上班)。非常感谢您的宝贵时间 Facelets 本质上是使用 JSP 定义页面的替代品。

以上是关于如何将现有的 JSF 组件添加到我自己的自定义组件中?的主要内容,如果未能解决你的问题,请参考以下文章

将现有的 Webdriver 对象传递给 Robot Framework 的自定义 Python 库

如何将 Google 地图搜索框添加到我的自定义地图?

JSF 为组件声明定义自定义命名空间

jsf 2.0 自定义组件/标签不复合

将 UIScrollView 委托设置为它自己的自定义类

JSF 组件渲染器中的 JSF 标记