Обновление данных в Wicket - PullRequest
       29

Обновление данных в Wicket

1 голос
/ 08 сентября 2011

Мы разрабатываем новое приложение в Wicket и столкнулись с небольшой проблемой.

Что мы делаем:

1) создать новый SortableDataProvider
2) создать новый DefaultDataTablePagingInBottom
3) создать новый WebMarkupContainer
4) добавить DefaultDataTablePagingInBottom в WebMarkupContainer
5) создать новый AjaxCheckBox
6) в onUpdate AjaxCheckBox добавьте WebMarkupContainer в AjaxRequestTarget
7) установить SortableDataProvider на новый SortableDataProvider (с обновленным запросом)
8) DefaultDataTablePagingInBottom.replaceWith (новый DefaultDataTablePagingInBottom - с новым провайдером).

Что происходит:

1) Установите флажок -> ничего не происходит.
2) Нажмите еще раз -> crash: «Последняя причина: этот метод можно вызывать только для компонента, который уже был добавлен в его родительский элемент.
WicketMessage: метод onRequest интерфейса org.apache.wicket.behavior.IBehaviorListener, предназначенный для org.apache.wicket.ajax.markup.html.form.AjaxCheckBox$1@1a2fefd для компонента [[Component id = checkBox]], вызвал исключение "
3) Нажмите обратно в браузере -> список, который я отфильтровал с новым поставщиком.

Есть идеи?

--- EDIT --- Вот некоторый код.

1) В конструкторе веб-страницы:

model = new Model(projectPlannerService);
provider = new SortableProjectDataProvider(model, (WebSession) getSession(), isChecked);
table = new DefaultDataTablePagingInBottom("table", columns, provider, 50);

listContainer = new WebMarkupContainer("wmc");

listContainer.add(table);
add(listContainer.setOutputMarkupId(true));

/*
 * checkbox för filtrering
 */
AjaxCheckBox checkBox = new AjaxCheckBox("checkBox", new Model()) {

    @Override
    protected void onUpdate(AjaxRequestTarget target) {
        target.add(listContainer, "wmc");
        isChecked = !isChecked;
        provider = new SortableProjectDataProvider(model, (WebSession) getSession(), isChecked);
        updateTable();
    }
};
add(checkBox);

2) В updateTable ():

table.replaceWith(new DefaultDataTablePagingInBottom("table", columns, provider, 50));

3) SortableProjectDataProvider:

// Constructor
public SortableProjectDataProvider(IModel<?> model, WebSession webSession, boolean isChecked) {
    this.model = model;
    this.projectPlannerService = (ProjectPlannerService) model.getObject();
    this.webSession = webSession;
    setSort("customer", SortOrder.ASCENDING);
    System.out.println("ischecked:" + isChecked);
    if(!isChecked)
        list = ((ProjectPlannerService) model.getObject()).findAllProjects();
    else
        list = ((ProjectPlannerService) model.getObject()).findAllActiveProjects();

    System.out.println("size: " + list.size());

    comparator = new ProjectComparator();
}

public Iterator<Project> iterator(int first, int count) {

    Collections.sort(list, comparator);
    if (first > list.size()) {
        first = 0;
    }
    if (first + count > list.size()) {
        return list.subList(first, list.size()).iterator();
    } else {
        return list.subList(first, first + count).iterator();
    }
}

public IModel<Project> model(Project object) {
    return new DetachableProjectModel((Project) object);
}

public int size() {
    return list.size();
}


private class DetachableProjectModel extends LoadableDetachableModel {

    private Long id;
    @SpringBean
    ProjectPlannerService projectPlannerService;

    public DetachableProjectModel(Long id) {
        Injector.get().inject(this);
        if (id == null) {
            throw new IllegalArgumentException();
        }
        this.id = id;
    }

    public DetachableProjectModel(Project project) {

        this(project.getPk());
        Injector.get().inject(this);
    }


    public int hashCode() {
        return id.hashCode();
    }


    public boolean equals(final Object obj) {
        if (obj == this) {
            return true;
        } else if (obj == null) {
            return false;
        } else if (obj instanceof DetachableProjectModel) {
            DetachableProjectModel other = (DetachableProjectModel) obj;
            return other.id == this.id;
        }
        return false;
    }


    protected Object load() {
        return ((ProjectPlannerService) model.getObject()).findProjectById(id);
    }
}

}

калитка: расширение
-входная калитка: id = "checkBox" type = "checkbox" - Показать активную - / input-
-div калитка: id = "wmc" -
-table wicket: id = "table" - / table-
- / div-
- / Калитка: простирающийся

Заранее спасибо!
/ Andreas

Ответы [ 2 ]

1 голос
/ 11 сентября 2011

Заменив экземпляр вашего SortableProjectDataProvider на новый, вы усложните свою жизнь. Вместо использования boolean isChecked в конструкторе вы можете использовать IModel<Boolean>. Назначьте тот же экземпляр этой модели вашему поставщику данных и флажок, и все готово. Не нужно ничего заменять в onUpdate, добавить listContainer в AjaxRequestTarget и все должно работать ...

, например

...

private IModel<Boolean> isCheckedModel = new Model<Boolean>(Boolean.FALSE);

...

provider = new SortableProjectDataProvider(model, (WebSession) getSession(), isCheckedModel);

...

AjaxCheckBox checkBox = new AjaxCheckBox("checkBox", isCheckedModel) {

    @Override
    protected void onUpdate(AjaxRequestTarget target) {
        target.add(listContainer);
    }
};

...

Почти никогда не стоит заменять подобные вещи новыми в Wicket. Инкапсулируйте изменения в модели и измените / замените объект модели. Каждый объект, имеющий ссылку на эту модель, может видеть обновленное значение или изменять его при необходимости.

Надеюсь, это поможет.

0 голосов
/ 09 сентября 2011

Попробуйте это:

Неверно: target.add (listContainer, "wmc");
Справа: target.add (listContainer);

Неправильный; table.replaceWith (новый DefaultDataTablePagingInBottom («таблица», столбцы, поставщик, 50));
Справа: DefaultDataTablePagingInBottom tmp = new DefaultDataTablePagingInBottom («таблица», столбцы, поставщик, 50);
table.replaceWith (TMP);
таблица = tmp;
(Вы заменяете DefaultDataTablePagingInBottom, но не свою ссылку.)

// олл

...