2011-09-29 8 views
1

이미지에서 설명하려고했던 문제가 있습니다. 필요한 부분을 모두 이해하는 데 도움이되기를 바랍니다.위젯의 부모 페이지 구성 요소에서 하위 페이지 구성 요소 호출

<wicket:extend> 
    <div wicket:id="bodyPanel"></div> 
</wicket:extend> 

에서이처럼 자료 페이지의 자식

<div class="colContainer"> 
    <div class="leftColumn" > 
     <div wicket:id="menuNavPanel"></div> 
    </div> 
    <div class="rightColumn"> 
     <wicket:child/> 
    </div> 
</div> 

그리고 뉴욕 BIA 페이지 : enter image description here

내 자료 페이지 (menuNavPanel 트리 패널이다)이 같다 내 트리 패널, 노드를 클릭하면 코드는 다음과 같습니다.

@Override 
     protected void onNodeLinkClicked(AjaxRequestTarget target, TreeNode node) { 
      super.onNodeLinkClicked(target, node); 
      DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)node; 
      Unit unitObject =(Unit) treeNode.getUserObject(); 

      // I want to call bodyPanel fo child page passing the unitObject param 


     } 

이제 부모 페이지의 트리 패널에서 unitObject 매개 변수를 전달하는 childPanel fo 하위 페이지를 호출 할 수 있습니까?

내 문제를 표현할 수 있습니까? 도와 줘서 고마워.

답변

4

오버라이드 방법을 사용하는 대신 Wicket 1.5로 업그레이드하고 새로운 event bus을 사용하여 구성 요소간에 통신합니다.구성 요소의 유스 케이스에 특정한 사용자 정의, 유형 안전 이벤트를 작성할 수 있습니다 (예 : "ItemAddedToShoppingCart"또는 "GlobalThermoNuclearWarStarted").

linked article in the 1.5 migration guide은 설정 방법에 대한 충분한 정보를 제공합니다. 나는이 문제에 직면 하였을 때

3

정확하게 que 질문을 잘 이해하지 못합니다. BasePage은 왼쪽 열을 TreePanel으로 정의하고 하위 클래스를 오른쪽 열 div 내에서 확장 할 수 있도록합니다. 보통은 BodyPanelBasePages의 하위 클래스에 넣습니다. 이제 TreePanel의 일부 이벤트에서 BodyPanel의 메소드를 호출하려고합니다.

TreePanel에서 getPage()까지 호출되는 BasePage의 재정의 가능한 메소드를 사용하여 수행 할 수 있습니다. 자녀 페이지는 해당 메소드를 재정의하고 해당 구현은 보유한 BodyPanel을 호출합니다. 필요한베이스 페이지를 서브 클래 싱 왜 사용자의 특정 요구 및 구현의 세부 사항에 대한 나의 무지에서

public class BasePage ... { 
    // Hook 
    public void treePanelSelected(Object someObject) { } 
    ... 
} 

public class ChildPage extends BasePage ... { 

    BodyPanel bodyPanel; 
    @Override 
    public void treePanelSelected(Object someObject) { 
     bodyPanel.selectionChanged/(someObject); 
    } 
    ... 
} 


public class TreePanel ... { 

    ... 
    @Override 
     protected void onNodeLinkClicked(AjaxRequestTarget target, TreeNode node) { 
      super.onNodeLinkClicked(target, node); 
      DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)node; 
      Unit unitObject =(Unit) treeNode.getUserObject(); 

      ((BasePage)getPage()).treePanelSelected(unitObject); 
     } 
    } 

, 내가 볼 수 없습니다. 베이스 페이지에 BodyPanel을 추가하고 같은 클래스에서 제어 할 수 있습니다.

+1

시간과 좋은 예를 들어 주셔서 감사합니다. 마침내 이벤트 버스로 끝냈습니다. – Shahriar

+0

여러분을 환영합니다! 당신은 옳은 일을했습니다. 나는 지금까지 wicket 1.3에 붙어있다. 그래서 아직 많이 알려지지 않은 멋진 개선이있다. ( –

1

두 가지 방법이 있습니다. 하나는 더 깨끗하지만 더 많은 코드가 필요합니다. 다른 하나는 빠르고 더러운 것입니다.

방법 1 : 부모 페이지가 확대되고 있기 때문에 (좋은)

, 당신은 당신의 아이 페이지에서 구현

protected abstract WebMarkupContainer getBodyPanel(); 

같은 부모의 추상적 인 방법을 제공하고 적절한를 반환 할 수 있습니다 패널. 그런 다음 상위 페이지의 패널에서 해당 메소드를 호출 할 수 있습니다. 이는 다른 사용자가 제안한 재정의 할 수있는 방법과 유사합니다.

방법 2 : (나쁜)는

개찰구 구성 요소 계층 구조

은 부모와 자식 페이지 사이에 공유됩니다. 당신이 당신의 bodyPanel 고유 wicketId을 가지고 있으며, 페이지의 루트에 직접 추가되어 있는지 확인한다면, 당신은 아마

get("bodyPanelId"); 

를 호출 할 수 있으며 적절한 패널을 반환합니다.

+0

나는 추상적 인 getBodyPanel()을 배치하는 것이 실제로 가능할 것이라고 생각하지만 실제로 OOP 연습은 좋지 않을 것이다. 기본 페이지는 그렇지 않다. 서브 패널을 가질 수 있다는 것을 알아야하고, 그것을 얻을 수있는 방법을 제공 할 필요가 없어야합니다. 이벤트를 트리거 할 수있는 treepanel이 있다는 사실을 알고 있어야합니다. 게다가 기본 페이지를 만들 것입니다. abstract. –

+0

Hrm. 동의한다. 여기에 남겨 두겠다.하지만 게시물을 부딪히는 것이다.'getBodyPanel()'은 다른 시나리오에서 도움이 될 수있다. – jbrookover

+0

고맙습니다. 그러나 기본 페이지를 서브 클래 싱하는 것이 처음부터 올바른 결정 인 경우에는 의미가 있습니다. OP가 제공 한 정보에서 모든 하위 클래스가'BodyPanel' 만 추가한다고 가정하면'BodyPanel' (또는 적어도 일반화)이 실제로 기본 페이지의 일부인 것으로 보입니다. –

1

, 나는 해결하는 방법은 두 가지 생각이 (이전 1.5) :

가) 여기에 설명 된 같은 이벤트의 다른 구성 요소를 통지 관찰자 패턴의 변화를 구현 : Realising complex cross-component ajax actions in wicket - The observer way

b) wicket 방문자를 사용하여 동일한 구성 요소 트리를 탐색합니다.

변형 된 a)를 사용하기로 결정했으나 구성 요소에서 페이지 구현으로 연결되어 패널 자체를 테스트 할 때 문제가 발생합니다. 아마 b)는 더 좋은 아이디어 일 것입니다. 그러나 제 응용 프로그램이 구현 된 상태에서 아주 부드럽게 실행되고 다음 단계는 1.5와 이벤트 버스로 전환 될 것입니다. 아직 시도하지 않았습니다. b).

+2

이벤트 버스는 원래 1.4 버전에 대해 개발되었으며 https://issues.apache.org/jira/browse/WICKET-1312에서 패치를 찾을 수 있습니다. 1.4에 적용 할 수 있는지 알아 보는 것은 흥미로울 수 있습니다.x 신청 –

+0

감사합니다, 당신의보기는 차갑다. 1.5로 이동 했으므로 이벤트 버스를 사용하는 것을 선호했습니다. – Shahriar

+0

@MartijnDashorst 이것은 b)를 구현했기 때문에, 어떻게 작동하는지 (1.4 패치) ... 시도해 보겠습니다. 재미 있습니다;) – Nicktar

2

감사합니다 모두, 마침내 martijn이 정의한 이벤트 버스 방법을 선택하지 않은 모든 멋진 옵션을 검토했습니다. 내가 한 것은 이벤트 페이로드를 만들고 대화를 위해 패널을 연결 한 것입니다. 또한 선택된 ID/엔티티를 수신 패널로 전달해야했습니다.

모델을 수동으로 할 필요가 없도록 트리 요소의 모델에 따라 수신 패널의 복합 속성 모델을 설정하는 방법이 있습니까?

public class TreeNodeClickUpdate { 

    private final AjaxRequestTarget target; 

    private final long selectedId; 

    /** 
    * Constructor 
    * 
    * @param target 
    * @param selectedId 
    */ 
    public TreeNodeClickUpdate(AjaxRequestTarget target, long selectedId) 
    { 
     this.target = target; 
     this.selectedId = selectedId; 
    } 

    /** @return ajax request target */ 
    public AjaxRequestTarget getTarget() 
    { 
     return target; 
    } 

    public long getSelectedId() { 
     return selectedId; 
    } 
} 

송신자 측에이 같은 짓을했는지 :

send(getPage(), Broadcast.BREADTH, 
     new TreeNodeClickUpdate(target, unitObject.getId())); 

내가 이런 식으로있어 수신 끝에 :

나는 당분간이 좋아했다

  @Override 
      public void onEvent(IEvent<?> event) { 
       super.onEvent(event); 

      if (event.getPayload() instanceof TreeNodeClickUpdate) 
      { 
       TreeNodeClickUpdate update = (TreeNodeClickUpdate)event.getPayload(); 
       setSelectedId(update.getSelectedId()); //sets to id field of panel 
       update.getTarget().add(this); 
      } 


      } 

예를 들어 수신 패널에서 값을 얻으려면 다음과 같은 라벨을 만들어야합니다.

label = new Label("label",new PropertyModel<BiaHomePanel>(this,"selectedId")); 

나중에 실제로 엔티티의 정보를 얻고 양식으로 보여주고 싶습니다. 더 좋은 방법으로 모델을 전달할 수있는 좋은 방법이 있을까요, 아니면 이벤트 페이로드에서 매개 변수로 전달해야할까요?

관련 문제