2015-10-15 74 views
0

我正在尝试扩展Wicket Library Repeater/Contacts Editor示例,以便保存正在编辑的行,但在更改值之后它不会更新。更新Wicket 6.0刷新行的问题刷新视图示例

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); 
    } 
} 
+0

更新时是否刷新LDM?尝试使用AbstractReadOnlyModel或更新行时强制在LDM上进行分离? – Imperative

+0

我不确定。我认为它应该自动更新,因为我认为我使用的是相同的用户对象。我不确定如何使用AbstractReadOnlyModel或如何分离LDM。值得一提的是,“删除”链接按预期工作(它将用户对象的删除设置为true)并刷新表格。 – matthewh86

+0

找到最简单的方法是在'load'方法中打印。当你点击保存按钮并刷新行时,它必须被调用。 – Imperative

回答

0

我已经设法解决这个问题,通过使用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)); 
     } 

    }; 
0

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

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

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

+0

我已经更改了示例,以便每次刷新列表时都会调用getItemModels()而不是传递它,但我仍然认为问题在于,当我更新TextField(通过键入它)时,底层用户不会更新,因为ActionPanel的getDefaultModelObject调用没有我在屏幕上做出的更改。 – matthewh86