2013-04-05 3 views
7

사용자가 원하는대로 항목을 고정하고 제거 할 수있는 동적 대시 보드를 사용하고 있습니다. 이제는 기존의 복합 컴포넌트를 백업 빈의 뷰에 추가하고 싶다는 문제점이 있습니다. 나는 인터넷에서 이것을하는 정확한 방법을 찾으려고 노력했지만 지금까지는 성공하지 못했다. 여기 프로그래밍 방식으로 백킹 빈에 복합 구성 요소를 만들고 추가합니다.

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

이 복합 구성 요소를 반환해야하는 코드입니다 :

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

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

을 그리고이 기능을 사용하고 어떻게되어 여기에 추가 할 단순 복합 구성 요소입니다

그러나 아무 것도 열 안에 렌더링되지 않습니다. 이것이 어떻게 이루어질 수있는 아이디어가 있습니까? 렌더링 된 = "# {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); } } 

따라서, 특정 예에서 사용 'HtmlUtil.getCompositeComponent'를 호출하는 3- 라이너? –

답변

11

이 코드는 불완전합니다. 컴포지트 구성 요소 구현에 복합 구성 요소 리소스를 포함하려면 나중에 FaceletContext#includeFacelet()을 사용해야합니다. 이 작업을 수행하는 유틸리티 메소드가 있습니다. EL 범위에서 #{cc}을 만들어야하는 상황이기 때문에 부모님이 손에 있어야합니다. 따라서이 유틸리티 메소드는 컴포지트를 지정된 부모의 자식으로 즉시 추가합니다. 또한, 복합 컴포넌트에 고정 ID를 지정하는 것이 중요합니다. 그렇지 않으면 JSF는 복합 컴포넌트 내부에서 양식/입력/명령 컴포넌트를 처리 할 수 ​​없습니다. 당신은 어디에서 호출하는 :

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

매우 흥미 롭습니다! 외부 구성 요소를 포함하기 위해이 방법을 사용할 수 있습니까? 기존 자원을 사용하는 대신 응용 프로그램 내에 정의되지 않은 구성 요소를 포함하고자합니다. – fnst

+1

@fnst : 사용자 지정 리소스 처리기로 필요한 경우 리소스를 제어 할 수 있습니다. 궁극적으로 유효한 'URL'로 끝나는 한, 기본적으로 모든 것을 가리킬 수 있습니다 (예 :'file : //','http : //'등등, 사용자 정의 프로토콜을 포함하여 DB 접근이 이론적으로 가능합니다) . – BalusC

+0

답변 해 주셔서 감사합니다. :) 복합 컴포넌트의 속성으로 값 표현식을 추가 할 수 있습니까? – drodil