在备份bean中以编程方式创建和添加复合组件 [英] Programmatically create and add composite component in backing bean

查看:123
本文介绍了在备份bean中以编程方式创建和添加复合组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用动态仪表板,用户可以根据需要固定和移除项目。现在我有一个问题,我想添加现有的复合组件到支持bean的视图。我试图找到从互联网这样做的正确方法,但迄今没有成功。以下是我要添加的简单复合组件:

I am working with a dynamic dashboard where users can pin and remove items as they like. Now I have a problem that I want to add existing composite component to the view from the backing bean. I've tried to find correct way to do this from the internet but no success so far. Here is the simple composite component I want to add:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:composite="http://java.sun.com/jsf/composite">
    <!-- INTERFACE -->
    <cc:interface>

    </cc:interface>

    <!-- IMPLEMENTATION -->
    <cc:implementation>
        <h:outputText value="TEST"/>
    </cc:implementation>
</html>

这里是应该返回复合组件的代码:

Here is the code which should return the composite component:

public static UIComponent getCompositeComponent(String xhtml, String namespace) {
    FacesContext fc = FacesContext.getCurrentInstance();
    Application app = fc.getApplication();
    Resource componentResource = app.getResourceHandler().createResource(xhtml, namespace);

    UIPanel facet = (UIPanel) app.createComponent(UIPanel.COMPONENT_TYPE);
    facet.setRendererType("javax.faces.Group");
    UIComponent composite = app.createComponent(fc, componentResource);
    composite.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, facet);

    return composite;
}

这里是我使用的功能:

Column column = new Column();
UIComponent test = HtmlUtil.getCompositeComponent("test.xhtml", "comp");
column.getChildren().add(test);

但是列中没有任何内容。有什么想法可以怎么做?我不想用render =#{bean.isThisRendered}的方法,因为它不符合我的用例。

But nothing is rendered inside the column. Any ideas how this could be done? I don't want to go with the rendered="#{bean.isThisRendered}" way because it does not fit in my use case.

推荐答案

此代码不完整。您需要使用 FaceletContext#includeFacelet() 之后,将复合组件资源包含在复合组件实现中。这是一个实现该工作的实用方法。让父母掌握很重要,因为在EL范围内应该创建#{cc} 的上下文。因此,此实用程序方法也会立即将组合作为给定父项的子代添加。此外,重要的是给复合组件一个固定的ID,否则JSF将无法处理组合中的任何表单/输入/命令组件。

This code is incomplete. You need to use FaceletContext#includeFacelet() afterwards to include the composite component resource in the composite component implementation. Here's an utility method which does the job. It's important to have the parent at hands, as it is the context where the #{cc} should be created in the EL scope. So this utility method also immediately adds the composite as a child of the given parent. Further, it's important to give the composite component a fixed ID, otherwise JSF wouldn't be able to process any form/input/command components inside the composite.

public static void includeCompositeComponent(UIComponent parent, String libraryName, String resourceName, String id) {
    // Prepare.
    FacesContext context = FacesContext.getCurrentInstance();
    Application application = context.getApplication();
    FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);

    // This basically creates <ui:component> based on <composite:interface>.
    Resource resource = application.getResourceHandler().createResource(resourceName, libraryName);
    UIComponent composite = application.createComponent(context, resource);
    composite.setId(id); // Mandatory for the case composite is part of UIForm! Otherwise JSF can't find inputs.

    // This basically creates <composite:implementation>.
    UIComponent implementation = application.createComponent(UIPanel.COMPONENT_TYPE);
    implementation.setRendererType("javax.faces.Group");
    composite.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, implementation);

    // Now include the composite component file in the given parent.
    parent.getChildren().add(composite);
    parent.pushComponentToEL(context, composite); // This makes #{cc} available.
    try {
        faceletContext.includeFacelet(implementation, resource.getURL());
    } catch (IOException e) {
        throw new FacesException(e);
    } finally {
        parent.popComponentFromEL(context);
    }
}

所以,在你的具体例子中,使用它如下:

So, in your particular example, use it as follows:

includeCompositeComponent(column, "comp", "test.xhtml", "someUniqueId");

这篇关于在备份bean中以编程方式创建和添加复合组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆