Decorator Component in Wicket
Is it possible to implement some kind of decorator component in wicket ? Specially while honoring the id of the decorated component ?
Currently 开发者_高级运维i try to solve this using a Border Component acting as a decorator:
Given:
public XXXPage()
{
MyBorder border = new MyBorder("xxx");
border.add( new Label("xxx", "Foo") ); // label just as simplification. Its really a Component that we want to surround the anchor (linkify) around.
add(border);
}
XXXPage.html
<body>
<span wicket:id="xxx"/>
</body>
MyBorder.html
<wicket:border>
<a wicket:id="link"><wicket:body/></a>
</wicket:border>
MyBorder.java
public MyBorder(String id)
{
super(id);
AjaxLink link = new AjaxLink("link")
{
@Override public void onClick(AjaxRequestTarget arg0)
{
}
};
add(link);
link.add(getBodyContainer()); // from javadoc of Wicket's Border
}
Gives:
org.apache.wicket.WicketRuntimeException: The component(s) below failed to render. A common problem is that you have added a component in code but forgot to reference it in the markup (thus the component will never be rendered).
1. [Component id = xxx]
at org.apache.wicket.Page.checkRendering(Page.java:1182)
So in essence, the xxx component should be wrapped in a transparent manner with a link component. This xxx is out of control.
In a "banana wicket" implementation this would be a possible pseudo code:
Component wrapWithAction(Component a) {
// now wrap
Link b = new Link() {
// handle link onClick and all that
}
b.wrap(a);
return b;
}
//
Depends on what kind of stuff your decorator wants to do. The regular meaning of decorating is to have object B assume the role of object A, providing exactly the same contract, using A to implement that contract, but do something extra on top of that. I think that that's not a very common case with Widgets. Rather you are looking to reuse some part (the UI and state, maybe behavior). In general, in my opinion, this works best through using panels and markup inheritance.
Technically, borders are the out-of-the-box reusable solution for decorating, but in practice they prove to be a bit hairy to work with. For relatively straightforward way of doing simple decorations, see my answer on Generating commented-out content with Wicket (which uses the somewhat undocumented way Wicket's rendering pipeline works). Also shows that Wicket's behaviors are a very flexible way to modify behavior of existing components without requiring those components themselves to be changed. Other than that, I would just design for reuse explicitly.
I think you'd have better luck adding either a WebMarkupContainer or Fragment within your ListView than anything else.. These two can both contain other Components such as Links, Labels, etc..
Let me know if you need more help..
Add an AjaxEventBehavior for "onclick" to the Component. The example in the Javadoc I linked does what you want.
You can add Behaviors to almost anything in Wicket, that's one of its most powerful features.
精彩评论