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

牧云@^-^@ 提交于 2019-12-08 10:13:56

问题


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

回答1:


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.




回答2:


Can you try calling MessagePanel.this.modelChanged() before adding it to the target?




回答3:


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.



来源:https://stackoverflow.com/questions/5617983/why-doesnt-my-wicket-panel-rerender-after-changing-the-default-model

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!