我想创建自定义组件,将新子项添加到页面“head”facet。
此自定义组件基于h:selectOneMenu。在jsf页面上使用时,用户只需更改当前主题即可。我需要这个组件做的是将样式表子项添加到head facet。
我的组件有支持java。我试图在encodeBegins()方法中修改“head”,但我的孩子根本没有渲染。看一下实现:
@FacesComponent(value = "com.ramps.util.ThemeSelector")
public class ThemeSelector extends UIInput implements NamingContainer {
public void encodeBegin(FacesContext context) throws IOException {
UIComponent headFacet = context.getViewRoot().getFacet("javax_faces_location_HEAD");
Resource res = new Resource();
res.setName("...");
...
List <UIComponent> headChildren = headFacet.getChildren();
headChildren.add(res);
super.encodeBegin(context);
}
}
是否可以直接从我的自定义组件的后台java修改“head”facet?如果是的话,我错过了什么? 此致
答案 0 :(得分:4)
UIViewRoot有一个方法可以将资源组件添加到视图的 head 目标中:
public void addComponentResource(FacesContext context,UIComponent componentResource): 将假定代表资源实例的componentResource添加到当前视图。资源实例由a呈现 资源渲染器(如ScriptRenderer,StylesheetRenderer)为 在标准HTML RenderKit中描述。这种方法会导致 要在视图的“head”元素中呈现的资源。
对于您的情况,该组件是一个UIOutput,其属性为 name ,呈现类型为 javax.faces.resource.Stylesheet 。
您可以在将自定义组件添加到视图后添加样式表资源。你做这个,注册它以收听PostAddToViewEvent。 UIInput已经实现了ComponentSystemEventListener,因此您必须覆盖processEvent。
这是添加样式表的组件的工作示例。
@FacesComponent("CustomComponent")
@ListenerFor(systemEventClass=PostAddToViewEvent.class)
public class CustomComponent extends UIInput{
@Override
public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
if(event instanceof PostAddToViewEvent){
UIOutput resource=new UIOutput();
resource.getAttributes().put("name", "theme.css");
resource.setRendererType("javax.faces.resource.Stylesheet");
FacesContext.getCurrentInstance().getViewRoot().addComponentResource(FacesContext.getCurrentInstance(), resource);
}
super.processEvent(event);
}
}
我想知道使用复合组件对于您尝试做的事情并不容易。