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