向页面“head”添加新子元素的自定义 JSF 组件刻面

发布于 2024-09-16 06:57:52 字数 773 浏览 3 评论 0原文

我想创建自定义组件,将新的子组件添加到页面“head”方面。

该自定义组件基于 h:selectOneMenu。当在jsf页面上使用时,用户可以简单地更改当前主题。我需要这个组件做的是将样式表子项添加到头方面。

我的组件有支持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”方面?如果是这样,我错过了什么?
问候

I want to create custom component which adds new child to page "head" facet.

This custom component is based on h:selectOneMenu. When used on jsf page, user can simply change the current theme. What I need this component to do is to add stylesheet child to head facet.

My component has backing java. I tried to modify "head" in encodeBegins() method, but my child is not rendered at all. Take a look at the implementation:



@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);
  }
 }

Is it possible to modify "head" facet directly from backing java of my custom component? If so, what am I missing?
Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疧_╮線 2024-09-23 06:57:53

UIViewRoot 有一个方法可以将资源组件添加到视图的 head 目标中:

public void addComponentResource(FacesContext context, UIComponent componentResource):
将假定表示资源实例的 componentResource 添加到当前视图。资源实例由
资源渲染器(例如 ScriptRenderer、StylesheetRenderer)为
标准 HTML RenderKit 中描述。该方法会导致
要在视图的“head”元素中呈现的资源。

对于您的情况,该组件是一个 UIOutput,具有属性 name 和呈现类型 javax.faces。资源.样式表

您可以在将自定义组件添加到视图后添加样式表资源。您制作此内容,将其注册为侦听 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);
    }

}

我想知道使用复合组件对于您想要做的事情来说是否更容易。

UIViewRoot has a method to add a resource component to the head target of the view:

public void addComponentResource(FacesContext context, UIComponent componentResource):
Add componentResource, that is assumed to represent a resource instance, to the current view. A resource instance is rendered by a
resource Renderer (such as ScriptRenderer, StylesheetRenderer) as
described in the Standard HTML RenderKit. This method will cause the
resource to be rendered in the “head” element of the view.

For your case, the component is an UIOutput with an attribute name and a render type of javax.faces.resource.Stylesheet.

You can add the stylesheet resource after your custom component is added to the view. You make this, registering it for listening to PostAddToViewEvent's. The UIInput already implements ComponentSystemEventListener so you have to override processEvent.

This is a working example of a component that adds a stylesheet.

@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);
    }

}

I wonder if using a composite component is not easier for what you are trying to do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文