2014-10-10 57 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