2014-04-13 9 views
1

JSF 페이지에서 HtmlInputText를 동적으로 표시하려고합니다. 그러나, 나는 받고있다jsf 상태를 복원하는 동적 구성 요소

javax.faces.FacesException: Cannot add the same component twice: j_idt10:hitDyn 

페이지에 대한 첫 번째 요청 중에는 입력 텍스트가 잘 렌더링된다. 이 예외는 페이지를 다시 게시하는 동안 발생합니다. 입력 구성 요소에 텍스트를 입력하고 Enter 키를 누르면 예외가 발생합니다. 은 .xhtml 페이지에서 다음 코드가 있습니다, 백킹 빈에서

<h:form> 
    <h:outputLabel value="Welcome!"></h:outputLabel> 
    <f:metadata> 
     <f:event type="preRenderView" listener="#{dynamicBacking.addDynComp}" /> 
    </f:metadata> 
    <h:panelGroup id="dynOuter"></h:panelGroup> 
</h:form> 

을 나는 다음과 같은 코드를 가지고 : 나는의 상태를 복원 할 몇 가지 문제가 있다고 생각

@ManagedBean(name="dynamicBacking") 
public class DynamicBacking { 
    public void addDynComp() { 
     Application app = FacesContext.getCurrentInstance().getApplication(); 
     HtmlInputText hit = (HtmlInputText)app.createComponent(HtmlInputText.COMPONENT_TYPE); 
     hit.setId("hitDyn"); 
     UIComponent parent = findComponent("dynOuter"); 
     if(parent != null) { 
      parent.getChildren().add(hit); 
     } 
    } 

    public UIComponent findComponent(final String id) { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     UIViewRoot root = context.getViewRoot(); 
     final UIComponent[] found = new UIComponent[1]; 
     root.visitTree(new FullVisitContext(context), new VisitCallback() {  
      @Override 
      public VisitResult visit(VisitContext context, UIComponent component) { 
       if(component.getId().equals(id)){ 
        found[0] = component; 
        return VisitResult.COMPLETE; 
       } 
       return VisitResult.ACCEPT;    
      } 
     }); 
     return found[0]; 
    } 
} 

을 다시 게시의 동적 구성 요소. JSF 페이지의 수명주기에서 너무 늦은 동적 구성 요소를 추가하고 있습니까? ASP.NET에서 Page.Load 단계에서 동적 컨트롤을 추가 할 수 있다는 것을 알고 있습니다. 하지만 지금까지 JSF에서 동일한 방법을 달성하는 방법을 생각해 낼 수는 없습니다. 도와주세요!

+0

내가 리스너 방법은 포스트 백에 호출되는 것을 생각하며 다시 같은 구성 요소를 추가하려고하지만, 이미 존재하고 그에 대한 예외를 얻을 : 다음 코드는 포스트 백을 확인하는 방법을 보여줍니다. –

+0

리스너 메소드가 포스트 백에서 호출 될 때 구성 요소가 이미 존재하는 이유는 무엇입니까? 다시 게시하는 동안 누가 구성 요소를 만들었습니까? –

+0

구성 요소가 초기 페이지로드시 트리에 추가됩니다. 다시 게시를 수행 할 때 리스너가 다시 호출되고 동일한 ID를 가진 다른 구성 요소를 추가하려고 시도합니다. –

답변

0

구성 요소가 초기 페이지로드시 트리에 추가 되었기 때문에 예외가 나타납니다. 다시 게시를 수행 할 때 리스너가 다시 호출되고 동일한 ID를 가진 다른 구성 요소를 추가하려고 시도하면 예외가 발생합니다. 문제의 해결 방법은 구성 요소를 추가 할 때 요청이 다시 게시가 아닌지 확인하는 것입니다.

if (FacesContext.getCurrentInstance().isPostback()) {....