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

我现在的问题是,我需要插入例如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");

预先感谢

最佳答案

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

JSF组件可以通过两种方式包含其他控件:作为子控件或命名构面。组件始终控制着它们如何呈现其构面。如果要渲染自己的 child ,则必须为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");
  }

10-07 19:11
查看更多