Why doesn't my Wicket panel restart after changing the default model?

When the page with the first MessagePanel displays, the message and the approval link are rendered perfectly. When I click on the approval link, all business logic works as desired, the getNextMessage() method returns the corresponding object, but the message bar does not refresh on the page in the browser. That is, the message body label is not updated.

JPAEntityModel extends LoadableDetachableModel.

What am I missing? And how to 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); } 
0
source share
3 answers

This is because you are not using the model correctly.

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

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

Even worse, when you click on the link, the panel is assigned a new model:

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

But this, obviously, does not affect the label model, since it is already set to the original value.

So, there are two things that need to be changed in order to make it work. First, your shortcut 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 is not necessarily the best solution, but it is a working solution that demonstrates how models can be used dynamically.)

And ideally, you should not replace the model when you click on the link, just change the model object. If you need a custom model class ( JPAEntityModel ), you still should not accept the pre-constructed model in the panel constructor, but only the first message object. The reason the current implementation does not apply the use of JPAEntityModel from the very beginning, only after the first click of the link.

+4
source

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

0
source

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

0
source

Source: https://habr.com/ru/post/1390466/


All Articles