简体   繁体   中英

Why doesn't my Wicket Panel rerender after changing the default model?

When the page with the MessagePanel first renders, the message and the approve link render perfectly. When I click the approve link, all the business logic works as desired, the getNextMessage() method returns the appropriate object, but the message panel does not update on the page in the browser. That is, the message body Label does not update.

JPAEntityModel extends LoadableDetachableModel.

What am I missing? And how do I fix it?

public class MessagePanel(String id, IModel<Message> messageModel) extends Panel {
  super(id, messageModel);
  add(new Label("messageText", new PropertyModel<Message>(getModelObject(), Message.BODY_FIELD)));
  add(new IndicatingAjaxFallbackLink<User>("approveLink", new JPAEntityModel<User> (getActiveUser())) {
    @Override
    public void onClick(AjaxRequestTarget target) {
      Message nextMessage = getNextMessage();
      MessagePanel.this.setDefaultModel(new JPAEntityModel<Message>(nextMessage));
      target.add(MessagePanel.this);
    }
});
  setOutputMarkupId(true);
}

It is because you're not using the model properly.

This line takes the value of the panel's model object, as it is set during construction , and uses it to create the component model.

add(new Label("messageText", new PropertyModel<Message>(getModelObject(), Message.BODY_FIELD)));

To make matters worse, when you click the link, the panel is given a new model:

MessagePanel.this.setDefaultModel(new JPAEntityModel<Message>(nextMessage));

But this obviously doesn't affect the model of the label, as it is already set to refer to the original value.

So there are two things you need to change to make it work. First off, your label model should use your panel model directly:

new Model<Message>() {
  @Override
  public Message getObject() {
    return MessagePanel.this.getModelObject().getMessage(); //or something similar
  }
}

(Note: the code above isn't necessarily the best solution, but it is a working solution that demonstrates how models can be used dynamically.)

And ideally you shouldn't replace the model when you click the link, just change the model object. If you need a custom model class ( JPAEntityModel ), you shouldn't be accepting a pre-constructed model in the panel constructor anyway, just the first message object. The reason being the current implementation doesn't enforce the use of JPAEntityModel from the start, only after the first click of the link.

您可以在将MessagePanel.this.modelChanged()添加到目标之前尝试调用它吗?

You must use call setOutputMarkupId(true) within you MessagePanel . The panel needs to have a markup identifier to be able to update the markup DOM in the browser.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM