Как добавить существующие компоненты JSF в мои собственные компоненты?
-
19-08-2019 - |
Вопрос
У меня есть класс тегов, который расширяет UIComponent и UIOutput. В этом классе у меня есть encodeBegin и encodeEnd, которые я могу использовать своим contextWriter для вывода любого html-тега своего рода, который я тоже хочу, используя writer.startElement (& Quot; div & Quot ;, 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");
Заранее спасибо
Решение
Вы не можете использовать 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");
}
Другие советы
Не совсем ответ, скорее предположение, но, возможно, вы могли бы расширить один из элементов управления Facelets?
В качестве альтернативы, либо используйте Facelets напрямую - что, кажется, именно то, что вы действительно хотите, хотя я сам не использовал его. Или вы можете добавить элементы управления UIOutput, где вы хотите, чтобы HTML отображался, и установить значение каждого для HTML, который вы хотите отобразить - это именно то, что f: verbatim делает под капотом, или, как кажется, просматривая исходный код: - ) р>