为什么我的Wicket Panel在更改默认模型后没有重新渲染?

时间:2011-04-11 07:14:45

标签: java ajax jpa wicket

首次呈现带有MessagePanel的页面时,消息和批准链接呈现完美。当我单击批准链接时,所有业务逻辑都按预期工作,getNextMessage()方法返回相应的对象,但消息面板不会在浏览器的页面上更新。也就是说,邮件正文标签不会更新。

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

3 个答案:

答案 0 :(得分:4)

这是因为您没有正确使用该模型。

此行采用面板模型对象的值,,因为它在构造期间设置,并使用它来创建组件模型。

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

更糟糕的是,当您点击链接时,面板会获得一个新模型:

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

但这显然不会影响标签的模型,因为它已经设置为引用原始值。

因此,您需要更改两件事才能使其正常工作。首先,您的标签模型应直接使用您的面板模型:

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

(注意:上面的代码不一定是最好的解决方案,但它是一个工作解决方案,演示了如何动态使用模型。)

理想情况下,单击链接时不应替换模型,只需更改模型对象即可。如果你需要一个自定义模型类(JPAEntityModel),你不应该接受面板构造函数中的预构建模型,只需要接受第一个消息对象。当前实施的原因是,只有在第一次点击链接后,才会从一开始就强制使用JPAEntityModel

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您必须使用setOutputMarkupId(true)内的来电MessagePanel。面板需要有一个标记标识符才能更新浏览器中的标记DOM。