2014-10-10 60 views
3

我有一個面板(見下面的BasePanel),它有一個項目列表和一個「動作」欄,其中放置按鈕。單擊這些按鈕可以通過模型更改列表中的項目。如何使用Wicket正確模擬子面板?

現在我想要相同的面板,但使用稍微不同的按鈕(請參閱下面的CustomPanelA和CustomPanelB)。我有三個面板按鈕的配置。

我該如何建模?我以爲使用wicket:child,但由於按鈕位於另一個不起作用的檢票組件內。

BasePanel.java

class BasePanel extends Panel { 
    public BasePanel(String id) { 
     super(id); 

     // note: I need this container for refreshing using AJAX 
     WebMarkupContainer outer = new WebMarkupContainer("outerContainer"); 
     outer.setOutputMarkupId(true); 
     add(outer); 

     // ... create listview 
     outer.add(new ListView("items") { /* implementation of listview */ }; 

     // This container is necessary to show/hide the buttons 
     WebMarkupContainer actionbar = new WebMarkupContainer("outerContainer"); 
     actionbar.setOutputMarkupId(true); 

     // ... create default buttons 
     actionbar.add(new Link("add") { /* implementation of link */); 
    } 
} 

BasePanel.html

<html> 
<wicket:panel> 
    <div wicket:id="outerContainer"> 
     <div wicket:id="actionbar" > 
       <a wicket:id="add">Add</a> 
     </div> 
     <div wicket:id="items"> 
       <!-- ... markup for items is here --> 
     </div> 
    </div> 
</wicket:panel> 
</html> 

CustomPanelA.java

class CustomPanelA extends BasePanel { 
    public CustomPanelA (String id) { 
     super(id); 

     // add additional buttons only 
     actionbar.add(new Link("actionA1") { /* implementation of link */); 
     actionbar.add(new Link("actionA2") { /* implementation of link */); 
    } 
} 

CustomPanelA.html

<html> 
<wicket:extend> 
    <a wicket:id="actionA1">ActionA1</a> 
    <a wicket:id="actionA2">ActionA2</a> 
</wicket:extend> 
</html> 

CustomPanelB.java

class CustomPanelB extends BasePanel { 
    public CustomPanelB (String id) { 
     super(id); 

     // add additional buttons only 
     actionbar.add(new Link("action_b1") { /* implementation of link */); 
     actionbar.add(new Link("action_b2") { /* implementation of link */); 
    } 
} 

CustomPanelB.html

<html> 
<wicket:extend> 
    <a wicket:id="action_b1">Action b1</a> 
    <a wicket:id="action_b2">Action b2</a> 
</wicket:extend> 
</html> 

回答

2

有很多您的問題的解決方案。我會告訴你其中的一個。

正如您所提到的基於<wicket:child/>的方法,那麼我會就此構建我的決定。您的BasePanel將爲抽象類,它將包含除動作鏈接以外的所有組件。它將提供一個抽象的方法,例如稱爲addActionLinks

class abstract BasePanel extends Panel { 
    public BasePanel(String id) { 
     super(id); 

     //...your code. 
     WebMarkupContainer actionBar = ...; 

     //call this abstract method to add links in actionBar. 
     addActionLinks(actionBar); 
    } 

    public abstract void addActionLinks(WebMarkupContainer container); 
} 

HTML:

<wicket:panel> 
    ... 
    <div wicket:id="actionbar" > 
     <wicket:child/> 
    </div> 
    ... 
</wicket:panel> 

而對於其他面板,你只需要實現addActionLinks方法:

class CustomPanelA extends BasePanel { 
    public CustomPanelA (String id) { 
     super(id); 
    } 

    protected void addChildren (WebMarkupContainer container) 
    { 
     actionbar.add(new Link("actionA1") { /* implementation of link */); 
     actionbar.add(new Link("actionA2") { /* implementation of link */); 
    } 
} 

和HTML:

<wicket:extend> 
    <a wicket:id="actionA1">ActionA1</a> 
    <a wicket:id="actionA2">ActionA2</a> 
</wicket:extend> 

當然,您需要使用您的BasePanel動作鏈接實施另一個面板,並將其從我的實施中移除(例如,創建DefaultBasePanel類)。

此外,您還可以爲BasePanel中的操作鏈接創建另一個ListView,並且還可以從一種方法獲取它們,並按子類重寫。

另外,也許,使用片段也可以解決您的問題。你可以看here以瞭解更多關於片段的信息。

我認爲,還有更多的方法,但出於某種原因,這一個出現在我的腦海。希望這可以幫助。

+1

哇,這是很多的信息。感謝您展示不同的方式如何做到這一點。 :-) – Friederike 2014-10-11 17:43:50

4

我認爲一個更好的解決方案是使用RepeatingViews。這樣你甚至不需要爲子面板提供html。

BasePanel.java

class BasePanel extends Panel { 

protected final RepeatingView actionbar; 

public BasePanel(String id) { 
    super(id); 

    // note: I need this container for refreshing using AJAX 
    WebMarkupContainer outer = new WebMarkupContainer("outerContainer"); 
    outer.setOutputMarkupId(true); 
    add(outer); 

    // ... create listview 
    outer.add(new ListView("items") { /* implementation of listview */ }; 

    // This container is necessary to show/hide the buttons 
    actionbar = new RepeatingView("action"); 

    // ... create default buttons 
    actionbar.add(new Link("add") { /* implementation of link */ }. 
     setBody(Model.of("Add")); 
} 
} 

BasePanel.html

<html> 
<wicket:panel> 
<div wicket:id="outerContainer"> 
    <div class="actions"> 
      <a wicket:id="action"></a> 
    </div> 
    <div wicket:id="items"> 
      <!-- ... markup for items is here --> 
    </div> 
</div> 
</wicket:panel> 
</html> 

CustomPanelA.java

class CustomPanelA extends BasePanel { 
public CustomPanelA (String id) { 
    super(id); 

    // add additional buttons only 
    actionbar.add(new Link("actionA1") { /* implementation of link */); 
    actionbar.add(new Link("actionA2") { /* implementation of link */); 
} 
} 

CustomPanelB.java

class CustomPanelB extends BasePanel { 
public CustomPanelB (String id) { 
    super(id); 

    // add additional buttons only 
    actionbar.add(new Link("action_b1") { /* implementation of link */); 
    actionbar.add(new Link("action_b2") { /* implementation of link */); 
} 
} 

注:RepeatingView裏面可以添加繼承RepeatingView組件的標記任何部件。只要確保你不添加相同的組件id兩次,你會沒事的。

+0

是的,我已經提到了'ListView'方法(並且認爲它與'RepeatingView'類似),但是在某些情況下,您需要使用標記來更好地放置元素(例如將換行鏈接到表格中)和樣式允許通過HTML放置CSS標籤,而不是使用'AttributeAppender'或覆蓋)。在這種情況下,您必須將所有來自父面板的標記放入子面板中。此外,您的方法必須在放置鏈接的地方使用方法,因爲否則所有子面板都會從「BasePanel」鏈接「添加」。 – 2014-10-10 13:18:20

+0

當然,「添加」按鈕是可選的,創建一個可覆蓋的方法也是非常重要的。 我覺得最好不要讓這些組件具有標記,使用AttributeAppenders和setBody()更好的路線。 – cserepj 2014-10-10 17:17:15

+0

也謝謝你的回答。雖然這是一個完全有效的解決方案,但我首選Michaels,因爲我可以爲子面板設置不同的標記。 ;-) – Friederike 2014-10-11 17:43:00