如果我有一个包装在div中的输入(与其他东西一起(,
如何将添加到包装器中的任何 beavior 传递给该输入?
例:
组件 HTML 就像<div> <img> <input> ...
然后我想像add( new MyComponent("foo", model).add( new AjaxEventBehavior("onupdate"){ ... }
一样添加它(但这不起作用,因为只有FormComponent
可以接收(AjaxEventBehavior的(。
我假设我可以将此行为对象从包装器移动到输入,但不知道在哪里 - 是否有一些"构造后"侦听器?
还是我应该完全不同地做,比如将行为作为参数传递?
保持如上的原因是为了使其对组件的用户透明。
您可以重写包装组件的 MarkupContainer#add(Behavior... behaviors)
方法。这当然意味着包装组件永远不会收到任何行为:
public class MyWrappingComponent extends Panel {
private TextField<?> field;
// Constructors and stuff..
@Override
public Component add(Behavior... behaviors) {
field.add(behaviors);
return this;
}
}
一种选择是将包装组件分离为Border
,可用于用内容包围组件。但是,这会降低包装元素的"透明度"。(请参阅 Javadoc 页面上的示例(。
public class MyWrappingBorder extends Border {
public MyWrappingBorder(String id) {
// add the <img />
// add the <div />
}
...
}
// The markup
<wicket:border>
<div>
<img />
<wicket:body /> <!-- Will be replaced with the added content -->
</div>
</wicket:border>
然后像这样使用它:
add(new MyWrappingBorder("border")
.add(new TextField<String>("input").add(/* the behaviors */)));
使用这种标记
<div wicket:id="border">
<input type="text" wicket:id="input" />
</div>
Border
的方法将使您能够重用边框组件而不使用"TextField?"组件。 例如,如果要添加下拉列表:
add(new MyWrappingBorder("border")
.add(new DropDownChoice<String>("input", listOfChoices)));
在包装器中包含返回组件的抽象方法。
public abstract class WrapperComponent extends Panel
{
public WrapperComponent(String id)
{
super(id);
add(getInnerComponent("whateveridyouwant"));
//Other wrapper stuff
}
public abstract Component getInnerComponent(String id);
}
然后调用 WrapperComponent 将强制你重写 getInnerComponent 方法。
WrapperComponent wrapperComponent = new WrapperComponent("wrapperComponent")
{
@Override
public Component getInnerComponent(String id)
{
TextField textfield = new TextField(id);
textField.add(behavior);
return textfield;
}
}
这种方式允许您定义当您实际决定使用 WrapperComponent 时所需的内部组件和行为。它可以更好地控制您可以使用内部组件执行的操作。
希望对您有所帮助。