【问题标题】:Vaadin - Refresh grid after row modificationVaadin - 行修改后刷新网格
【发布时间】:2015-08-06 16:44:43
【问题描述】:

我用数据库中的数据创建简单的网格:

BeanItemContainer<Customer> container = new BeanItemContainer<>(Customer.class, customerRepository.findAll());
Grid grid = new Grid(container);

要编辑创建按钮的每一行:

Button edit = new Button("Edit", clickEvent -> openWindow((Customer) grid.getSelectedRows().iterator().next()));

此打开带有编辑表单的新窗口。接受所有更改后,我必须手动刷新整个页面以查看网格上的修改。我的问题是:

修改任何行条目后如何仅刷新 Grid? 以及如何将这些修改保存到数据库(也许 beanItemContainer 可以做到)?

【问题讨论】:

标签: java vaadin vaadin7 vaadin-grid


【解决方案1】:

这是一个错误。在底层容器中完成更改后,网格不会自行更新,也没有任何合理的刷新方法。围绕这个问题有几个技巧,即

grid.clearSortOrder();

grid.setEditorEnabled(true);
grid.setEditorEnabled(false);

SSCCE:

TextField text =  new TextField("Edit");
Grid grid;
BeanItemContainer<Customer> container;

@Override
protected void init(VaadinRequest request) {
    final VerticalLayout layout = new VerticalLayout();
    container = new BeanItemContainer<>(Customer.class, Arrays.asList(new Customer("1"), new Customer("2")));
    grid = new Grid(container);
    Button open = new Button("open");
    open.addClickListener(this :: openListener);
    Button save = new Button("save");
    save.addClickListener(this :: saveListener);
    layout.addComponents(grid, open, save, text);
    setContent(layout);
}

private void openListener(Button.ClickEvent clickEvent){
    text.setValue(((Customer) (grid.getSelectedRow())).getName());
}
private void saveListener(Button.ClickEvent clickEvent){
    Customer c = (Customer) grid.getSelectedRow();
    c.setName(text.getValue());
    grid.clearSortOrder();
}

可能重复Update Grid with a fresh set of data, in Vaadin 7.4 app

【讨论】:

  • 非常感谢。您对clearSortOrder() 的建议非常有效。此外,对于任何只想刷新一行的人,有一些提示:Vaadin Forum
  • 如果这是一个错误,您是否有相关的 Vaadin 错误跟踪编号/链接?
【解决方案2】:

使用 Vaadin 8,在添加或删除行或更改基础数据后刷新网格:

grid.getDataProvider().refreshAll();

【讨论】:

  • 不幸的是,这在 Vaadin 8 中不起作用。我每次都需要明确地设置项目。
  • @Aubergine 如果您使用 setItems() 开始设置数据,那么可以,因为这会创建一个包装项目列表的 DataProvider,因此您需要显式更新项目。
  • @Aubergine 但如果您使用从数据存储(例如,RDBMS)动态获取数据的 DataProvider,那么 refreshAll() 方法会像宣传的那样工作。
【解决方案3】:

从 Vaadin 7.7.4 开始,网格中有一个 refreshRows(Object ... itemIds) 和一个 refreshAllRows() 方法:https://dev.vaadin.com/ticket/16765

【讨论】:

  • 就是这个方法,但是什么都不做(Vaadin 7.7.9)
  • 当我发布这个答案时它曾经工作过(大约一年前)。如果我是你,我会检查容器中的数据是否是最新的。
  • 当 Grid disabled 并且添加或修改行时 refreshAllRows() 不起作用,但 clearSortOrder() 确实
  • 这些家伙甚至可以控制他们的 api。 Wtf 用于刷新表。你应该给它一个项目列表,它应该渲染它,它有多难。强行与 Vaadin 合作工作,我讨厌它。从事网络开发已有 15 年了,从来没有处理过这种垃圾。
【解决方案4】:

我必须在每次调用 saveListener 事件后显式调用 grid.setItems() 以使我的 Vaadin 8.3 Grid 刷新网格内的数据。奇怪的是,视觉网格状态反映编辑的值。

Scala 实现:

var advicesList : mutable.MutableList[Advice] = null

private def initGrid() = {
  advicesList = mutable.MutableList(itmemsFromDB: _*)
  setItems(advicesList.asJava)

  getEditor.addSaveListener((event) => {
      val bean = event.getBean
      Notification.show("Saved value: " + bean)

      // ==== RELOAD GRID ITEMS AFTER EDITION
      val oldItemIdx = advicesList.indexOf(advicesList.filter(a => a.id == bean.id).head)
      advicesList.update(oldItemIdx, bean)
      event.getGrid.setItems(advicesList.asJava)
  })
}

【讨论】:

    【解决方案5】:

    有一种方法可以更好地解决问题:

    您必须从容器中获取BeanItem 并将其传递给您的编辑器窗口。在那里,您可以通过BeanItems Properies 对其进行访问来更改 bean 本身。这是一项非常手动的工作,所以我总是使用 FieldGroup 的数据绑定 - 只需调用 bind(field, "propertyName");其中 propertyName 是没有 get 和非大写字母的 getter 方法。

    【讨论】:

      猜你喜欢
      • 2019-01-23
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 2018-01-30
      • 1970-01-01
      • 2019-05-13
      • 2020-04-23
      • 1970-01-01
      相关资源
      最近更新 更多