Как добавить существующие компоненты JSF в мои собственные компоненты? - PullRequest
5 голосов
/ 17 марта 2009

У меня есть класс тегов, который расширяет UIComponent и UIOutput. В этом классе у меня есть encodeBegin и encodeEnd, которые я могу использовать с помощью contextWriter для вывода любого html-тега своего рода, который я тоже хочу, используя writer.startElement ("div", myComponent) и так далее.

Моя проблема сейчас в том, что мне нужно вставить, например, вместо использования 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");

Спасибо заранее

Ответы [ 2 ]

3 голосов
/ 17 марта 2009

Вы не можете использовать ResponseWriter , как хотите. Два способа, которыми я могу придумать, как программно добавлять дочерние элементы управления, это либо через атрибут binding ( см. Этот ответ ), либо в месте, где обычно создаются элементы управления (в JSP, то есть в классе тегов ).

Существует два способа для компонентов JSF содержать другие элементы управления: как дочерние или как именованные фасеты. Компоненты всегда контролируют, как они отображают свои фасеты; если они хотят отобразить своих детей, они должны вернуть true для 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");
  }
1 голос
/ 17 марта 2009

Не совсем ответ, скорее предположение, но, может быть, вы могли бы расширить один из элементов управления Facelets?

В качестве альтернативы, вы можете использовать лицевые грани напрямую - что, по-видимому, именно то, что вам нужно, хотя я сам этим не пользовался. Или вы можете добавить элементы управления UIOutput, где вы хотите, чтобы HTML отображался, и установить значение каждого из них в HTML, который вы хотите отобразить - это именно то, что f: verbatim делает под капотом, или так выглядит из исходного кода: )

...