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

发布于 2024-07-15 03:13:20 字数 650 浏览 18 评论 0原文

我有一个扩展 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");

提前致谢

I have a tag class which extends UIComponent and UIOutput. In this class I have encodeBegin and encodeEnd which I can use my contextWriter to output any kinda html tag I want too by using writer.startElement("div", myComponent) and so on.

My problem now is that I need to insert for example a instead of using the writer.startElement. I can get this done by doing getChildren().add(HtmlCommandButton button = new HtmlCommandButton()); but when doing it like that I cant seem to output the component where I want them to appear, like I can with write.startElement.

Does anyone have any good solutions in how I can take advantage of richfaces tags, JSF tags and similar in my own taglibrary? In short what I would really want to do is inside my encodeBegin:

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

Thanks by advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

咆哮 2024-07-22 03:13:20

您不能按照您的意愿使用ResponseWriter。 我可以想到如何以编程方式添加子控件的两种方法是通过绑定属性(查看此答案)或通常创建控件的位置(在 JSP 中,位于 标签类)。

JSF 组件可以通过两种方式包含其他控件:作为子控件或作为命名方面。 组件始终控制它们渲染面的方式; 如果要渲染其子级,则必须为 getRendersChildren

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

  @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");
  }

You cannot use the ResponseWriter as you wish to. Two ways I can think of how to add child controls programmatically are either via the binding attribute (see this answer) or in the place where controls usually get created (in JSPs, that is in the tag class).

There are two ways for JSF components to contain other controls: as children or as named facets. Components always control how they render their facets; if they are to render their children, they must return true for getRendersChildren.

This is untested code, but the sequence goes something like this:

  @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");
  }
栖竹 2024-07-22 03:13:20

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

或者,要么直接使用facelets——这似乎正是你想要的,尽管我自己没有使用过它。 或者,您可以在想要显示 HTML 的位置添加 UIOutput 控件,并将每个控件的值设置为您想要显示的 HTML - 这正是 f:verbatim 在幕后所做的事情,或者从源代码来看似乎是这样:- )

Not really an answer, more of a guess, but maybe you could extend one of the facelets controls?

Alternatively, either use facelets directly - which seems to be exactly what you want really though I've not used it myself. Or you could add UIOutput controls where you want HTML to appear and set the value of each to the HTML you want to appear - this is exactly what f:verbatim does under the hood, or so it seems from looking at the source code :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文