从wicket中的父页面组件调用子页面组件

时间:2011-09-29 10:30:24

标签: wicket

我有一个问题,我试图在Image中解释。我希望这将有助于所有人理解我需要的东西。 enter image description here

My Base Page就像这样(menuNavPanel是树面板):

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

作为Base Page的孩子的Ny BIA Page是这样的:

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

在我的树面板中,当我点击一个节点时代码为:

    @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


        }

现在,如何调用子页面的bodyPanel从父页面的树面板传递unitObject参数?

我能表达我的问题吗?希望得到一些帮助:)

5 个答案:

答案 0 :(得分:4)

不是执行覆盖方法,而是升级到Wicket 1.5并使用新的event bus在组件之间进行通信。您可以创建特定于组件用例的自定义类型安全事件:例如“ItemAddedToShoppingCart”或“GlobalThermoNuclearWarStarted”。

linked article in the 1.5 migration guide提供了有关如何设置内容的足够信息。

答案 1 :(得分:3)

我不确定我是否正确理解了问题。您的BasePage使用TreePanel定义了一个左列,并允许子类在右列div中展开。您通常会在BodyPanel的子类中放置BasePages。现在,您想要在BodyPanel上的某个事件上调用TreePanel的方法。

您可以在BasePage上使用可覆盖的方法来执行此操作,该方法将在TreePanelgetPage()中调用。您的子页面将覆盖该方法,其实现将调用它们持有的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);
        }
    }

由于我对你的具体需求和实现细节的无知,我不明白为什么需要继承子页面。您可以在BasePage中添加BodyPanel并从同一个类控制它。

答案 2 :(得分: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"));

后来,实际上我想从实体获取信息并以表格形式显示。是否有更好的方式以更好的方式传递模型,或者我应该作为事件有效负载中的参数传递。

答案 3 :(得分:1)

有两种方法可以做到这一点。一个更干净,但需要更多代码。另一个很快又脏。

方法1 :(好)

由于您的父页面正在扩展,您可以在父级中提供一个抽象方法,如

protected abstract WebMarkupContainer getBodyPanel();

在您的子页面中实现并返回相应的面板。然后,您可以从父页面的面板中调用该方法。这类似于其他用户建议的可重写方法。

方法2 :(差)

Wicket组件层次结构在父页面和子页面之间共享。因此,如果您确保bodyPanel具有唯一的wicketId并直接添加到页面的根目录,则可以直接调用

get("bodyPanelId");

它将返回正确的面板。

答案 4 :(得分:1)

当我遇到问题时,我想到了解决这个问题的两种方法(1.5之前):

a)实现观察者模式的变体,以通知其他组成部分,例如:Realising complex cross-component ajax actions in wicket - The observer way

b)使用wicket访问者遍历组件树。

我决定选择变体a)但是这会引入从组件到页面实现的耦合,这会导致在自己测试面板时出现问题。所以也许b)可能是更好的主意,但由于我的应用程序运行得相当顺利,a)已实现,下一个重要步骤将切换到1.5和事件总线,我还没有尝试过b)。