繁体   English   中英

更改默认型号后,为什么我的Wicket Panel不重新渲染?

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

第一次显示带有MessagePanel的页面时,消息和批准链接将完美呈现。 当我单击批准链接时,所有业务逻辑getNextMessage()预期工作, 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);
}

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

该行采用面板的模型对象的值(该值是在构建过程中设置的) ,并使用它来创建组件模型。

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都不应在面板构造函数中接受一个预先构建的模型,而只是第一个消息对象。 原因是当前的实现从一开始就没有强制JPAEntityModel的使用,仅在第一次单击链接之后。

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

您必须在MessagePanel使用调用setOutputMarkupId(true) 面板需要具有标记标识符,以便能够在浏览器中更新标记DOM。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM