Wicket攻击使用ListView,哪些替代?

时间:2017-08-03 13:17:24

标签: java frameworks wicket

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框架?

2 个答案:

答案 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()));