我尝试创建以下结构的页面:
MainPage {
DateSelector {}
TabGroup {
Tab0 {...}
Tab1 {...}
Tab2 {...}
}
}
DateSelector是一个组件(扩展Panel),使用户可以选择时间跨度(startDate,endDate)。 TabGroup扩展“AjaxTabbedPanel”。 TabGroup中显示的选项卡应使用选定的时间跨度来显示内容。
因此,如果用户在选择器中选择了一个时间跨度,则所选标签中的内容应该更新。
为此我实现了一个方法,DateSelector的用户可以覆盖它来更新其内容。
我觉得我的approch反对框架。我能以某种方式利用模型来增强实施吗?这有什么“错”?标签是否可以与DateSelector共享时间跨度,以便在时间跨度发生变化时更新?没有回调?
DateSelector的实现方式如下:
abstract public class TimespanSelectionPanel extends Panel {
public TimespanSelectionPanel(String id, Timespan timespan) {
super(id, new CompoundPropertyModel<Timespan>(timespan));
final DateTextField fromTextField = DateTextField.forDatePattern("from", "dd.MM.yyyy");
fromTextField.setOutputMarkupId(true);
fromTextField.add(new DatePicker());
final DateTextField toTextField = DateTextField.forDatePattern("to", "dd.MM.yyyy");
toTextField.setOutputMarkupId(true);
toTextField.add(new DatePicker());
fromTextField.add(new AjaxFormComponentUpdatingBehavior("onchange") {
@Override
protected void onUpdate(AjaxRequestTarget target) {
}
});
toTextField.add(new AjaxFormComponentUpdatingBehavior("onchange") {
@Override
protected void onUpdate(AjaxRequestTarget target) {
}
});
add(new AjaxLink<String>("today") {
@Override
public void onClick(AjaxRequestTarget target) {
updateComponent(fromTextField, toTextField, target, Timespan.today());
}
});
add(new AjaxLink<String>("yesterday") {
@Override
public void onClick(AjaxRequestTarget target) {
updateComponent(fromTextField, toTextField, target, Timespan.yesterday());
}
});
add(new AjaxLink<String>("lastMonth") {
@Override
public void onClick(AjaxRequestTarget target) {
updateComponent(fromTextField, toTextField, target, Timespan.lastMonth());
}
});
add(new AjaxLink<String>("actualMonth") {
@Override
public void onClick(AjaxRequestTarget target) {
Timespan timespan = adjustToTextField(fromTextField, toTextField, target, Timespan.actualMonth());
updateComponent(fromTextField, toTextField, target, timespan);
}
});
add(new AjaxLink<String>("fromTo") {
@Override
public void onClick(AjaxRequestTarget target) {
Timespan newTimespan = adjustToTextField(fromTextField, toTextField, target, fromTextField
.getModelObject(), toTextField.getModelObject());
update(target, newTimespan);
}
});
add(fromTextField);
add(toTextField);
}
private Timespan adjustToTextField(DateTextField fromTextField, DateTextField toTextField,
AjaxRequestTarget target, Timespan timespan) {
return adjustToTextField(fromTextField, toTextField, target, timespan.getFrom(), timespan.getTo());
}
private Timespan adjustToTextField(final DateTextField fromTextField, final DateTextField toTextField,
AjaxRequestTarget target, Date from, Date to) {
Date today = DateUtil.today();
if (to.after(today)) {
to = today;
toTextField.setModelObject(today);
target.addComponent(toTextField);
}
if (from.after(to)) {
from = to;
fromTextField.setModelObject(from);
target.addComponent(fromTextField);
}
return Timespan.fromTo(from, to);
}
private void updateComponent(final DateTextField fromTextField, final DateTextField toTextField,
AjaxRequestTarget target, Timespan newTimespan) {
fromTextField.setModelObject(newTimespan.getFrom());
toTextField.setModelObject(newTimespan.getTo());
target.addComponent(fromTextField);
target.addComponent(toTextField);
update(target, newTimespan);
}
abstract protected void update(AjaxRequestTarget target, Timespan timespan);
}
答案 0 :(得分:0)
如果选择器和选项卡面板之间的时间跨度始终保持同步,那么它是一个共享模型是有意义的。
这意味着您的选项卡面板需要访问提供TimeSpan的模型,或类似ITimeSpanProvider实现者(即时间跨度选择器组件)的模型。前者显然是在Wicket做事的更好方式。
因此,您的面板构造函数应该采用TimeSpan模型,然后由任何需要它的组件使用。这意味着您无需将模型更新从选择器推送到选项卡面板。
根据选项卡面板的功能,TimeSpan模型可能没有意义作为“主要”模型,但这没关系 - 它只是另一种模型。如果没有将时间跨度模型设置为选项卡面板中另一个组件的模型,那么您应该很好并在适当的时候分离()模型等。如果它适合您的情况,您可以将其全部抽象到TimeSpanAwarePanel中。做。