为什么我的 Wicket 面板在更改默认模型后不重新渲染?
当带有 MessagePanel 的页面首次呈现时,消息和批准链接会完美呈现。当我单击批准链接时,所有业务逻辑都按预期工作,getNextMessage()
方法返回适当的对象,但消息面板不会在浏览器中的页面上更新。即消息体Label不更新。
JPAEntityModel 扩展了 LoadableDetachableModel。
我缺少什么?我该如何解决它?
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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是因为你没有正确使用模型。
该行获取面板模型对象的值(在构建过程中设置),并使用它来创建组件模型。
更糟糕的是,当您单击链接时,面板会被赋予一个新模型:
但这显然不会影响标签的模型,因为它已经设置为引用原始值。
因此,您需要更改两件事才能使其发挥作用。首先,您的标签模型应该直接使用您的面板模型:(
注意:上面的代码不一定是最佳解决方案,但它是一个演示如何动态使用模型的可行解决方案。)
理想情况下,您不应该替换单击链接时的模型,只需更改模型对象即可。如果您需要自定义模型类 (
JPAEntityModel
),则无论如何您都不应该在面板构造函数中接受预先构造的模型,而只接受第一个消息对象。原因是当前的实现并不从一开始就强制使用JPAEntityModel
,仅在第一次单击链接后才强制使用。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.
To make matters worse, when you click the link, the panel is given a new model:
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:
(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 ofJPAEntityModel
from the start, only after the first click of the link.您可以在将其添加到目标之前尝试调用
MessagePanel.this.modelChanged()
吗?Can you try calling
MessagePanel.this.modelChanged()
before adding it to the target?您必须在
MessagePanel
中使用setOutputMarkupId(true)
调用。面板需要有一个标记标识符才能更新浏览器中的标记 DOM。You must use call
setOutputMarkupId(true)
within youMessagePanel
. The panel needs to have a markup identifier to be able to update the markup DOM in the browser.