Reputation: 15265
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);
}
Upvotes: 0
Views: 8814
Reputation: 49724
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.
Upvotes: 4
Reputation: 163
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.
Upvotes: 0
Reputation: 32397
Can you try calling MessagePanel.this.modelChanged()
before adding it to the target?
Upvotes: 0