2010-11-24 4 views
2

사용자 정의 UIComponent을 작성하고 그 안에 요소 (및 기타 주식 UIComponent)를 추가합니다. 구성 요소가 렌더링되지만 ViewRoot에서 찾을 수 없습니다. 같은 것을 추가JSF 2.0 : UIComponents와 그 내용을 추가하여 루트를 보는 방법은 무엇입니까?

ResponseWriter writer; 

@Override 
public void encodeBegin(FacesContext context) throws IOException { 
    writer = context.getResponseWriter(); 
    writer.startElement("div", this); 
    writer.writeText("testing", null); 
    writer.writeAttribute("id", getClientId(context) + ":testDiv", null); 
} 

@Override 
public void encodeEnd(FacesContext context) throws IOException { 
    writer.endElement("div");   
} 

:이 확인 렌더링

<x:myUiComponent id="myComponent" /> 

그러나 나는 구성 요소를 찾을 수 없거나는 ViewRoot에서 자식 DIV의 :

context.getViewRoot().findComponent("myComponent"); // returns null 
context.getViewRoot().findComponent("myComponent:testDiv"); // returns null 
findComponent("myComponent:testDiv"); // called within the custom component, throws java.lang.IllegalArgumentException? 

의 내가 있다고 가정 해 봅시다

다른 UIComponents를 사용자 정의 구성 요소의 하위 요소로 추가하려고하면 동일한 문제가 발생합니다. 그러나 사용자 구성 요소 자체가 거기에 있지 않기 때문에 구성 요소 트리에서 찾을 수 없습니다.

구성 요소 트리에 구성 요소를 가져 오려면 어떤 트릭이 필요합니까?

편집 : 질문을보다 잘 반영하도록 제목을 조정했습니다.

답변

1

이것은 바보 같은 실수로 인한 것입니다. 가정 하듯이 UIComponent이 자동으로 ViewRoot에 추가됩니다.그러나 나는이 질문에 대해 UIComponent (내 질문에 대해 이야기하고 있던 것)을 내 다른 사용자 정의 UIComponent (나는 거기에 있었다는 것을 잊어 버렸기 때문에 언급하지 않음)이라고 부릅니다.

UICodeEditor :

@Override 
public void encodeAll(FacesContext context) throws IOException { 
    UIEditPanel editor = new UIEditPanel(); 
    editor.encodeAll(context); 
} 

는 다음과 같은 템플릿이라고 : 여기

<!-- codeEditor is taghandler for UICodeEditor --> 
<x:codeEditor /> 

의 UICodeEditor 자동으로 ViewRoot 그러나 UIEditPane에 추가됩니다 않습니다 안쪽에 있지 않다. 왜냐하면 나는 단지 encodeAll(context)이라고 부르기 때문에 UIEditPanel은 그 부모를 알 수 없다. UIComponentBase에서 확장 (우리가 일반적으로하는 것처럼)이 아닌 수동으로 encodeAll(context)를 호출하지만, 단지 구성 요소를 추가하는 것 (어쩌면 더 나은)

editor.setParent(this); 

대체 방법 : 빠른 수정이 수동으로 하위 구성 요소의 부모를 설정하는 것입니다 encodeAll(...)에서 encodeBegin(...) 및하지에서 getChildren.add(...)와 자식으로 :

@Override 
public void encodeBegin(FacesContext context) throws IOException { 
    UIEditPanel editor = new UIEditPanel(); 
    getChildren().add(editor); 
} 

getChildren().add() 내부적으로 아이들의 부모로 현재 구성 요소를 추가합니다.

자식 생성 위치를 고려할 때 ResponseWriter을 사용할 필요가없는 경우 생성자에서 직접 생성하고 encodeXXX 메서드를 재정의하지 않는 것이 좋습니다 (해당되는 경우 해당 자식 요소를 재정의해야 함).). 그러나 필요에 따라 인코딩을 무시하고 수동으로 호출하는 것이보다 유연합니다.

사용자 지정 UIComponent는 <f:ajax render= 대상 일 수 없으므로 DOM 트리의 DOM 요소로 표시되지 않으므로주의해야합니다. 이것은 복합 컴포넌트와 같은 경우입니다. 복합 컴포넌트 구현을 panelGroup 관리 JSF로 래핑하여 나중에 내용을 다시 렌더링 할 수 있습니다.

4

getClientId(context)myComponent을 반환 할 것이라는 확신이 서지 않습니다. 실제로 구성 요소가 구성 요소에 중첩되어있는 경우 (예 : <h:form>) 해당 ID 앞에이 컨테이너 ID가 접두사로 붙습니다. 예를 들어

, 당신은 다음과 XHTML 페이지가있는 경우 :

context.getViewRoot().findComponent("myForm:myComponent"); 

context.getViewRoot().findComponent("myComponent:testDiv"); (또는 context.getViewRoot().findComponent("myForm:myComponent:testDiv");에 대해서는 그것을 :

<h:form id="myForm"> 
    <x:myUiComponent id="myComponent" /> 

는 다음 사용하여 구성 요소를 검색해야합니다을 null은 이러한 요소가 없으므로 JSF 구성 요소 트리을 반환합니다. 서버 측. 코드 :

writer.writeAttribute("id", getClientId(context) + ":testDiv", null); 

만의 HTML 생성 된 구성 요소ID 속성을 설정합니다 당신이 브라우저로 전송 HTML 페이지에 <div id="myForm:myComponent:testDiv">이있을 것이다 즉. 이 <div> 구성 요소는 JSF 구성 요소 트리에 존재하지 않으므로 Java 측에서 검색 할 수 없습니다.

+0

음, 맞습니다. getClientId (컨텍스트)는 실제로 JSF 생성 ID (이 경우 "j_id11")를 반환합니다. 자동으로 생성 된 ID를 setId()를 통해 UIComponents로 수동으로 대체해야합니다. 생성 된 ID는이 경우에 접두어를 가지지 않지만, 필자가 직접'h : body'에서 구성 요소를 호출합니다. 어쨌든, 커스텀 UIComponent를 어떻게 추가하여 컴포넌트 트리에 추가 할 수 있습니까? (예를 들어, AJAX 호출을 통해 다시 렌더링 할 수 있도록) 그게 가능하지 않다면 UIComponent 내부에 하위 요소를 추가하여 구성 요소 트리에 추가 할 수 있습니까? –

+0

입력 해 주셔서 감사합니다. 문제점을 발견했습니다 (내 답변 참조). 나는 이것이 심지어 그 질문에서 볼 수없는 무엇인가라고 생각한다. 나는 다음에 더 조심하려고 노력할 것이다! –

관련 문제