Java 重写CompoundPropertyModel中对象的getter方法
下面是我在Wicket中使用CompoundPropertyModel时经常遇到的一个问题的简单示例: 这是我的实体Java 重写CompoundPropertyModel中对象的getter方法,java,wicket,Java,Wicket,下面是我在Wicket中使用CompoundPropertyModel时经常遇到的一个问题的简单示例: 这是我的实体Item及其模型ItemModel和控制器ItemController: public class Item implements Serializable { private static final long serialVersionUID = 1L; private long createdTimestamp; public Item(long
Item
及其模型ItemModel
和控制器ItemController
:
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
private long createdTimestamp;
public Item(long createdTimestamp) {
super();
this.createdTimestamp = createdTimestamp;
}
public long getCreatedTimestamp() {
return createdTimestamp;
}
public void setCreatedTimestamp(long createdTimestamp) {
this.createdTimestamp = createdTimestamp;
}
}
public class ItemModel extends CompoundPropertyModel<Item> {
private static final long serialVersionUID = 1L;
public ItemModel(Item object) {
super(object);
}
}
public class ItemController {
public static int getDuration(Item item) {
return Days.daysBetween(new DateTime(item.getCreatedTimestamp()), new DateTime()).getDays();
}
}
这是可行的,但我不喜欢这个解决方案,因为如果您有很多实体,并且它们有很多字段,那么为所有实体创建和使用包装类可能会非常耗时
Item
已经有包装器,称为ItemModel
。这就是为什么我想在这个类中创建getter方法并强制模型使用它们
以下是我的意思的一个例子:
public class ItemModel extends CompoundPropertyModel<Item> {
private static final long serialVersionUID = 1L;
public ItemModel(Item object) {
super(object);
}
public Date getCreatedTimestamp() {
return new Date(getObject().getCreatedTimestamp());
}
public int duration() {
return ItemController.getDuration(getObject());
}
}
公共类ItemModel扩展了CompoundPropertyModel{
私有静态最终长serialVersionUID=1L;
公共项模型(项对象){
超级(对象);
}
公共日期getCreatedTimestamp(){
返回新日期(getObject().getCreatedTimestamp());
}
公共整数持续时间(){
返回ItemController.getDuration(getObject());
}
}
但是在这种情况下,getter方法将被模型忽略。到目前为止,我还没有发现如何强制模型使用它们。有什么方法可以做到这一点吗?您的模型没有被迫使用这些方法的原因是您的ItemModel类不是ItemView的子类。在Item模型的类声明中,使其扩展ItemView。此时父类的getter方法将被重写 更新:
我刚刚意识到ItemModel已经扩展了一个不同的类。在Java中,一个类只能扩展一个父类。这是个棘手的问题。一种方法是使ItemView成为CompoundPropertyModel的内部类,然后ItemModel扩展CompoundPropertyModel。这应该行得通。如果您在google“使java类扩展多个类”中遇到问题,并且有很好的结果。您的模型没有被迫使用这些方法的原因是您的ItemModel类不是ItemView的子类。在Item模型的类声明中,使其扩展ItemView。此时父类的getter方法将被重写 更新:
我刚刚意识到ItemModel已经扩展了一个不同的类。在Java中,一个类只能扩展一个父类。这是个棘手的问题。一种方法是使ItemView成为CompoundPropertyModel的内部类,然后ItemModel扩展CompoundPropertyModel。这应该行得通。如果您在google“使java类扩展多个类”中遇到问题,并且效果很好。CompoundPropertyModel在组件和属性之间有直接映射时非常有用。 但有时使用AROM更容易:
add(new Label("createdTimestamp", new AbstractReadOnlyModel<Date>() {
public Date getObject() {
return new Date(getModelObject().getCreatedTimestamp());
}
});
(因为我们实际上只是从Long转换到Date,所以最好使用转换器。)
项已具有名为ItemModel的包装器。这就是为什么我会这么做
希望在此类中创建getter方法并强制模型使用
他们
除了在IModel中定义的方法之外,模型永远不应该有其他方法——在那里添加的任何方法都不会被Wicket调用,但最终会在组件之间产生不必要的依赖关系(比如面板需要一个ItemModel作为参数)
为所有实体创建和使用包装器类可能非常耗时
我想知道你为什么要定义ItemModel。最好只接受构造函数中的任何模型:
public ItemPanel(String id, IModel<Item> itemModel) {
super(id, new CompoundPropertyModel<Item>(itemModel);
}
我见过其他我觉得有问题的模型实现。以下两种方法通常都有附加方法,可能是某种错误的气味:
new TransactionalModel(wrapped).commit()
new AsyncModel(wrapped).startAsync()
人们提倡创建与您的域相关的可重用模型,例如OrderSumModel,但我认为这是失败的。领域逻辑迟早会包含在模型中,您将看到以下模式出现:
BigDecimal sum = new OrderSumModel(order).getObject();
大多数时候,当我需要一些特别的东西时,我只是在编写匿名的内部类:
new Label("sum", new AbstractReadOnlyModel() {
public BigDecimal getObject() {
return service.calculateSum(getModelObject());
}
});
如上所述,使用Java 8和Wicket 8,编写起来更加容易:
new Label("sum", () -> service.calculateSum(getModelObject()));
总是有例外:当我需要一个具有复杂域逻辑的模型(例如OrderSumModel)时,我会将其作为一个嵌套的内部类。当我从多个位置需要它时,我会再次考虑。当组件和属性之间有直接映射时,CompoundPropertyModel非常有用。 但有时使用AROM更容易:
add(new Label("createdTimestamp", new AbstractReadOnlyModel<Date>() {
public Date getObject() {
return new Date(getModelObject().getCreatedTimestamp());
}
});
(因为我们实际上只是从Long转换到Date,所以最好使用转换器。)
项已具有名为ItemModel的包装器。这就是为什么我会这么做
希望在此类中创建getter方法并强制模型使用
他们
除了在IModel中定义的方法之外,模型永远不应该有其他方法——在那里添加的任何方法都不会被Wicket调用,但最终会在组件之间产生不必要的依赖关系(比如面板需要一个ItemModel作为参数)
为所有实体创建和使用包装器类可能非常耗时
我想知道你为什么要定义ItemModel。最好只接受构造函数中的任何模型:
public ItemPanel(String id, IModel<Item> itemModel) {
super(id, new CompoundPropertyModel<Item>(itemModel);
}
我见过其他我觉得有问题的模型实现。以下两种方法通常都有附加方法,可能是某种错误的气味:
new TransactionalModel(wrapped).commit()
new AsyncModel(wrapped).startAsync()
人们提倡创建与您的域相关的可重用模型,例如OrderSumModel,但我认为这是失败的。领域逻辑迟早会包含在模型中,您将看到以下模式出现:
BigDecimal sum = new OrderSumModel(order).getObject();
大多数时候,当我需要一些特别的东西时,我只是在编写匿名的内部类:
new Label("sum", new AbstractReadOnlyModel() {
public BigDecimal getObject() {
return service.calculateSum(getModelObject());
}
});
如上所述,使用Java 8和Wicket 8,编写起来更加容易:
new Label("sum", () -> service.calculateSum(getModelObject()));
总是有例外:当我需要一个具有复杂域逻辑的模型(例如OrderSumModel)时,我会将其作为一个嵌套的内部类。只要我需要不止一个