Wicket使用模型可能很麻烦。要使有状态页面正确呈现对象,您需要使用大量的样板代码,重写类以正确获取可见性状态等...一个简单的示例:
private IModel<FooBar> fooBarModel;
public MyPage() {
Label lbl1 = new Label("field1",
new PropertyModel<>(fooBarModel, "field1")) {
@Override public boolean isVisible() {
return fooBarModel.getObject().someCondition();
} }
add(lbl1);
/// Etc... same for dozen of other fields
}
我经常使用ListView
来帮助。同样的例子:
public MyPage() {
add(new ListView<FooBar>("content",
new SingleListModel<FooBar>(fooBarModel)) {
@Override protected void populateItem(...) {
FooBar fooBar = item.getModelObject();
// Code here gets simpler:
Label lbl1 = new Label("field1", fooBar.getField1());
lbl1.setVisible(fooBar.someCondition());
item.add(lbl1);
// Etc...
}
});
}
使用简单的实用工具类SingleListModel
,将IModel<T>
转换为ListModel<T>
,具有1或0个元素,具体取决于T是否为空:
public class SingleListModel<T>
extends LoadableDetachableModel<List<T>> {
private IModel<T> tModel;
public SingleListModel(IModel<T> tModel) {
this.tModel = tModel;
}
@Override
protected List<T> load() {
List<T> ret = new ArrayList<>(1);
T t = tModel.getObject();
if (t != null)
ret.add(tModel.getObject());
return ret;
}
}
这个好的副作用是整个&#34;内容&#34;如果fooBarModel
返回null
,则隐藏标记中的元素;无需特殊处理。
但所有这些对我来说都像是黑客,因为我以某种方式使用ListView
&#34;不自然&#34;方式。
是否有更简洁的方法可以获得相同的结果?标准的wicket框架?
答案 0 :(得分:1)
您应该使用行为来避免此类重复。
public class MyBehavior extends Behavior {
private final MyModel model;
public MyBehavior(MyModel model) {this.model = model;}
@Override public void onConfigure(Component c) {
if (model.someCondition()) {
component.setVisible(false);
}
}
}
用法:
MyBehavior b = new MyBehavior(modelInstance);
component1.add(b);
component2.add(b);
// dozen more
答案 1 :(得分:0)
Label lbl1 = new Label("field1",
new PropertyModel<>(fooBarModel, "field1")) {
@Override public boolean isVisible() {
return fooBarModel.getObject().someCondition();
} }
add(lbl1);
几乎没有重构,它可以转换为
add(new FLabel("id","text")
.setVisibilityFunction(()->model.getObject().isVisible()))
);
FLabel类:
public class FLabel extends Label implements IComponentWithVisibilityFunction<FLabel> {
private SerializableBooleanSupplier visibilityFunction;
public FLabel(String id) {
super(id);
}
public FLabel(String id, Serializable label) {
super(id, label);
}
public FLabel(String id, IModel<?> model) {
super(id, model);
}
@Override
public FLabel setVisibilityFunction(SerializableBooleanSupplier visibilityFunction) {
this.visibilityFunction = visibilityFunction;
return this;
}
@Override
protected void onConfigure() {
if (visibilityFunction != null) {
setVisible(visibilityFunction.getAsBoolean());
}
}
}
public interface IComponentWithVisibilityFunction<T> {
T setVisibilityFunction(SerializableBooleanSupplier visibilityFunction);
}
此外,您可以将供应商置于构造函数中:
add(new FLabel("id","text", ()->model.getObject().isVisible()));