无法更新Wicket 6.0 RefreshingView示例中的行

时间:2015-10-15 11:34:03

标签: java ajax wicket

我正在尝试扩展Wicket Library Repeaters / Contacts Editor示例,以便我可以保存我正在编辑的行,但在更改值后它不会更新。

http://www.wicket-library.com/wicket-examples-6.0.x/repeater/wicket/bookmarkable/org.apache.wicket.examples.source.SourcesPage?SourcesPage_class=org.apache.wicket.examples.repeater.FormPage&source=FormPage.java

调试代码,似乎

(User) ActionPanel.this.getDefaultModelObject()

没有获得更新的模型对象,只是最初用于填充RefreshingView的模型对象。

这是我目前的代码:

UserAdmin.java

package wicketsandbox.pages;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.RefreshingView;
import org.apache.wicket.markup.repeater.util.ModelIteratorAdapter;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.protocol.http.WebApplication;

import wicketsandbox.AccessProtector;
import wicketsandbox.DetachableUserModel;
import wicketsandbox.User;
import wicketsandbox.WicketSandboxApplication;
import wicketsandbox.panels.SignOutPanel;
import wicketsandbox.services.UserService;

public class UserAdmin extends WebPage {

    private static final long serialVersionUID = 1425344451953935626L;

    private Form<User> form;

    private final FeedbackPanel feedbackPanel;

    private RefreshingView<User> contactsGrid;

    private WebMarkupContainer updateableContactsForm;

    public UserAdmin() {
        new AccessProtector().userIsLoggedIn();

        Map<UUID, User> users = getUserService().getUsers();

        List<User> usersList = new ArrayList<User>();
        usersList.addAll(users.values());
        addContactsGridForm(usersList);

        this.add(new SignOutPanel("signOutPanel"));
        feedbackPanel = new FeedbackPanel("feedbackPanel");
        feedbackPanel.setOutputMarkupId(true);
        this.add(feedbackPanel);
    }

    private UserService getUserService() {
        return ((WicketSandboxApplication) WebApplication.get()).getUserService();
    }

    private void addContactsGridForm(final List<User> users) {
        updateableContactsForm = new WebMarkupContainer("updateableContactsForm");

        form = new Form<User>("contactsForm");

        contactsGrid = new RefreshingView<User>("contactsGrid") {

            private static final long serialVersionUID = 6885639412244652087L;

            @Override
            protected Iterator<IModel<User>> getItemModels() {
                return new ModelIteratorAdapter<User>(users) {

                    @Override
                    protected IModel<User> model(User user) {
                        System.out.println("L81" + user.toString());
                        return new CompoundPropertyModel<User>(new DetachableUserModel(user));
                    }
                };
            }

            @Override
            protected void populateItem(Item<User> item) {
                IModel<User> user = item.getModel();
                System.out.println("L90" + user.toString());
                item.add(new Label("id"));
                item.add(new TextField<String>("name", new PropertyModel<String>(user, "name")));
                item.add(new TextField<String>("username", new PropertyModel<String>(user, "username")));
                item.add(new TextField<String>("role", new PropertyModel<String>(user, "role")));
                item.add(new CheckBox("deleted", new PropertyModel<Boolean>(user, "deleted")));
                item.add(new ActionPanel("actions", user));
            }

        };
        updateableContactsForm.setOutputMarkupId(true);
        form.add(contactsGrid);
        updateableContactsForm.add(form);
        this.add(updateableContactsForm);
    }

    private class ActionPanel extends Panel {
        private static final long serialVersionUID = -2270412980024700449L;

        public ActionPanel(String id, final IModel<User> user) {
            super(id, user);
            System.out.println("L111" + user.toString());

            add(new AjaxLink<String>("save") {

                private static final long serialVersionUID = -1678664978510212524L;

                @Override
                public void onClick(AjaxRequestTarget target) {
                    getUserService().updateUser((User) ActionPanel.this.getDefaultModelObject());
                    System.out.println("L120" + user.toString());
                    info("User Saved: " + user.getObject().getName().toString());
                    target.add(feedbackPanel);
                }
            });

            add(new AjaxLink<String>("select") {

                private static final long serialVersionUID = 4555384514269762524L;

                @Override
                public void onClick(AjaxRequestTarget target) {
                    System.out.println("L132" + user.toString());
                    info("User Information: " + user.getObject().toString());
                    target.add(feedbackPanel);
                }
            });

            AjaxSubmitLink removeLink = new AjaxSubmitLink("remove", form) {

                private static final long serialVersionUID = 3030918214811303564L;

                @Override
                protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                    User user = (User) ActionPanel.this.getDefaultModelObject();
                    System.out.println("L145" + user.toString());
                    getUserService().removeUser(user);
                    info("Removed user " + user);
                    target.add(feedbackPanel);
                    target.add(updateableContactsForm);
                }
            };
            removeLink.setDefaultFormProcessing(false);
            add(removeLink);
        }
    }
}

DetachableUserModel.java

package wicketsandbox;

import java.util.Map;
import java.util.UUID;

import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.protocol.http.WebApplication;

public class DetachableUserModel extends LoadableDetachableModel<User> {

    private static final long serialVersionUID = 2518759982972547608L;

    private final UUID id;

    protected Map<UUID, User> getContacts() {
        return ((WicketSandboxApplication) WebApplication.get()).getUserService().getUsers();
    }

    public DetachableUserModel(User u) {
        this(u.getId());
    }

    public DetachableUserModel(UUID id) {
        if (id == null) {
            throw new IllegalArgumentException();
        }
        this.id = id;
    }

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

    /**
     * used for dataview with ReuseIfModelsEqualStrategy item reuse strategy
     * 
     * @see org.apache.wicket.markup.repeater.ReuseIfModelsEqualStrategy
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {
        if (obj == this) {
            return true;
        } else if (obj == null) {
            return false;
        } else if (obj instanceof DetachableUserModel) {
            DetachableUserModel other = (DetachableUserModel) obj;
            return other.id == id;
        }
        return false;
    }

    /**
     * @see org.apache.wicket.model.LoadableDetachableModel#load()
     */
    @Override
    protected User load() {
        return ((WicketSandboxApplication) WebApplication.get()).getUserService().getUser(id);
    }
}

2 个答案:

答案 0 :(得分:1)

我设法通过对每个可编辑的字段使用AjaxFormComponentUpdatingBehavior来解决这个问题。

    contactsGrid = new RefreshingView<User>("contactsGrid") {

        private static final long serialVersionUID = 6885639412244652087L;

        @Override
        protected Iterator<IModel<User>> getItemModels() {
            return new ModelIteratorAdapter<User>(getUserService().getUsers().values()) {

                @Override
                protected IModel<User> model(User user) {
                    return new CompoundPropertyModel<User>(new DetachableUserModel(user));
                }
            };
        }

        @Override
        protected void populateItem(final Item<User> item) {
            final IModel<User> user = item.getModel();
            item.add(new Label("id"));
            item.add(new TextField<String>("name").add(new AjaxFormComponentUpdatingBehavior("onchange") {

                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    item.setDefaultModelObject(user);
                }

            }));
            item.add(new TextField<String>("username").add(new AjaxFormComponentUpdatingBehavior("onchange") {

                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    item.setDefaultModelObject(user);
                }

            }));
            item.add(new TextField<String>("role").add(new AjaxFormComponentUpdatingBehavior("onchange") {

                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    item.setDefaultModelObject(user);
                }

            }));
            item.add(new CheckBox("deleted").add(new AjaxFormComponentUpdatingBehavior("onchange") {

                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    item.setDefaultModelObject(user);
                }

            }));
            item.add(new ActionPanel("actions", user));
        }

    };

答案 1 :(得分:0)

您的页面仅从服务加载一次用户:

Map<UUID, User> users = getUserService().getUsers();
List<User> usersList = new ArrayList<User>();
usersList.addAll(users.values());
addContactsGridForm(usersList);

每次调用#getItemModels()时,您都应该从服务中获取最新列表。