2013-04-05 45 views
7

我正在使用動態儀表板,用戶可以根據需要固定和刪除項目。現在我有一個問題,我想從支持bean中將現有的複合組件添加到視圖中。我試圖找到從互聯網上做到這一點的正確方法,但迄今爲止沒有成功。下面是簡單的複合組件我想補充:以編程方式在支持bean中創建和添加複合組件

<?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> 

這裏是一個要返回複合組件的代碼:

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}」的方式,因爲它不適合我的用例。

+0

出於興趣(題目是可怕的嚴重覆蓋,這會給我帶來前進光年):你在哪裏調用

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

所以,在你的具體的例子,按如下方式使用它3行調用'HtmlUtil.getCompositeComponent'? – 2017-06-21 16:27:56

回答

11

此代碼不完整。之後需要使用FaceletContext#includeFacelet()將複合組件資源包含在複合組件實現中。這是一個實用的方法。讓父母掌握這一點非常重要,因爲這是在EL範圍內創建#{cc}的上下文。因此,此實用程序方法也會立即將組合作爲給定父項的子項添加。此外,爲複合組件提供一個固定的ID非常重要,否則JSF將無法處理組合內的任何窗體/輸入/命令組件。

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

非常有趣!是否可以使用這種方法(可能有點改變)來包含外部組件?我不想使用現有資源,而是希望包含未在應用程序中定義的組件。 – fnst 2013-04-10 08:45:54

+1

@fnst:如果需要,可以使用自定義資源處理程序控制資源處理。只要你最終得到一個有效的'URL',它就可以基本指向所有的東西(包括'file://','http://'等等,甚至自定義的協議,以便例如DB訪問在理論上是可能的) 。 – BalusC 2013-04-10 10:57:06

+0

感謝您的回答,必須嘗試:)是否也可以將值表達式作爲屬性添加到複合組件中? – drodil 2013-04-11 11:45:39

相關問題