Wicket ListView ajax removes always removes last element in list

时间:2015-09-30 23:08:33

标签: java apache wicket

I have a way to add panels in a listview. Each panel is associated with an Object of type Type. I have an 'add' and an some 'remove' AjaxSubmitLinks. Both have setDefaultFormProcessing(false) because I want non-submitted / validated values to remain when someone add or removes an element. setReuseItems(true) is set for the ListView. Please see the code snippet below.

         ListView itemContainer = new ListView<Type>("list", getList()) {
            @Override
            protected void populateItem(final ListItem<Type> listItem) {
                final Component element = createComponent(listItem.getModel());
                listItem.add(element);
                listItem.add(new AjaxSubmitLink("remove") {

                    @Override
                    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                        getList().remove(listItem.getIndex());
                        target.add(wrapper);
                    }
                }.setDefaultFormProcessing(false));
            }
        };
        itemContainer.setReuseItems(true);
        add(itemContainer);
        add(new AjaxSubmitLink("add") {
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                Type object = addObject();
                getList().add(object);
                target.add(wrapper);
            }

            @Override
            public boolean isVisible() {
                return getList().size() < DSAddableField.this.max && isEditable();
            }
        }.setDefaultFormProcessing(false));

Where wrapper contains everything, so everything is reloaded with Ajax. All works well, expcet no matter which remove link I click the last element is being removed. equals() method is overriden on Type based on a UUID check. I did a debug and it would seem to me that the right element is removed from the ListModel, but wrong values are sent down by the ajax response.

How can I get this to work? I tried to remove setReuseItem(true), but than the non-saved values for list items were not reloaded. (Panels contain lot of input fields)

Any suggestions?

UPDATE:

I already tried to remove the object with getList().remove(listItem.getModelObject()), this was second solution but still failed.

Regardless if I use remove by index or by modelobject the right element is being removed from the list when using debugger.

UDAPTE 2:

If I remove "final int index = listItem.getIndex();" the right element is removed opposed to the last one but when I add a new one to the list non saved inputs are cleared which is the original problem I'm trying to solve. Please advise.

3 个答案:

答案 0 :(得分:2)

这属于你的第二个编辑:
如果您使用target.add(wrapper);,则会阅读整个组件,然后重新渲染它。 如果您将populateItem放在WebMarkupContainer中,则只能重新呈现此项目。

protected void populateItem(final ListItem<Type> listItem) {
    WebMarkupContainer cont = new WebMarkupContainer("cont");
    cont.setOutputMarkupId(true);
    cont.setOutputMarkupPlaceholderTag(true);
    final Component element = createComponent(listItem.getModel());
    cont.add(element);
    cont.add(new AjaxSubmitLink("remove") {
        @Override
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
           getList().remove(listItem.getIndex());
           target.add(cont);
        }
    }.setDefaultFormProcessing(false));    
    listItem.add(cont); 
}

答案 1 :(得分:0)

我自己检查了之前提供的解决方案,我应该这样做:

getList().remove(listItem.getModelObject());

虽然我不确定这不会只是给出一个新的列表。我会做这样的事情:

List<Type> myList = getList();
ListView itemContainer = new ListView<Type>("list", myList) {
    myList.remove(listItem.getModelObject());
}

答案 2 :(得分:0)

我认为问题是listItem.getIndex();

当您调用该方法来获取索引时,listItem将是列表中的最后一个元素。

尝试:

@Override
protected void populateItem(final ListItem<Type> listItem) {
    final Component element = createComponent(listItem.getModel());
    listItem.add(element);
    final int index = listItem.getIndex();
    listItem.add(new AjaxSubmitLink("remove") {
    @Override
    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
        getList().remove(index);
        target.add(wrapper);
    }
    }.setDefaultFormProcessing(false));