自定义JSF组件,它将新的子项添加到页面“head”facet

时间:2010-08-27 17:20:08

标签: jsf jsf-2 facelets custom-component

我想创建自定义组件,将新子项添加到页面“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?如果是的话,我错过了什么? 此致

1 个答案:

答案 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);
    }

}

我想知道使用复合组件对于您尝试做的事情并不容易。