Как использовать модель в калитке?

Я пытаюсь создать страницу следующей структуры:

MainPage {
    DateSelector {}
    TabGroup {
        Tab0 {...}
        Tab1 {...}
        Tab2 {...}
    }
}

DateSelector — это компонент (расширение Panel), который позволяет пользователю выбирать временной интервал (startDate, endDate). TabGroup, расширяющая «AjaxTabbedPanel». Вкладки, показанные в TabGroup, должны использовать выбранный промежуток времени для отображения содержимого.

Поэтому, если пользователь выбирает временной интервал в селекторе, содержимое выбранной вкладки должно обновляться.

Для этого я реализую метод, который пользователь DateSelector может переопределить, чтобы обновить его содержимое.

У меня такое чувство, что мой подход противоречит структуре. Могу ли я каким-то образом использовать модель для улучшения реализации? Что в этом «не так»? Могут ли вкладки совместно использовать временной интервал с 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);

}

person Arne Deutsch    schedule 16.04.2010    source источник


Ответы (1)


Если временной интервал между селектором и панелями вкладок всегда синхронизирован, то имеет смысл, что это общая модель.

Это означает, что вашим панелям вкладок нужен доступ либо к модели, предоставляющей TimeSpan, либо к чему-то вроде реализации ITimeSpanProvider (то есть к компоненту выбора временного интервала). Первый, очевидно, лучший способ сделать что-то в Wicket.

Таким образом, ваши конструкторы панелей должны использовать модель TimeSpan, которая затем используется всеми требуемыми компонентами. Это означает, что вам не нужно передавать обновления модели из селектора на панели вкладок.

В зависимости от функции ваших панелей вкладок модель TimeSpan может не иметь смысла в качестве «основной» модели, но это нормально — это просто еще одна модель. Если модель временного промежутка не установлена ​​в качестве модели для другого компонента на ваших панелях вкладок, вы должны быть любезны и detach() модели, когда это необходимо, и т. д. Вы можете абстрагировать все это в TimeSpanAwarePanel, если это соответствует тому, что вам нужно. делает.

person ireddick    schedule 20.04.2010