【问题标题】:Why doesn't my Wicket Panel rerender after changing the default model?为什么我的检票面板在更改默认模型后没有重新呈现?
【发布时间】:2011-04-11 07:14:45
【问题描述】:

当带有 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);
}

【问题讨论】:

    标签: java ajax jpa wicket


    【解决方案1】:

    那是因为你没有正确使用模型。

    此行获取面板模型对象的值,在构造过程中设置,并使用它来创建组件模型。

    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,只有在第一次点击链接之后。

    【讨论】:

    • 那么如何让标签刷新,从新模型对象中拉取数据?
    • 使用 new PropertyModel(getModel(), ...) 代替。
    • @Martijn Dashorst 这确实是理想的解决方案,但前提是链接也被修改以避免调用setDefaultModel()
    【解决方案2】:

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

    【讨论】:

    • 这并没有改变任何东西。我在示例中添加了更多内容,也许可以更清楚地说明。
    【解决方案3】:

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

    【讨论】:

    • 糟糕,忘记添加了。我有。
    猜你喜欢
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    相关资源
    最近更新 更多