简体   繁体   English

Vaadin - 行修改后刷新网格

[英]Vaadin - Refresh grid after row modification

I create simple grid with data from database: 我使用数据库中的数据创建简单网格:

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

To edit each row the button was created: 要编辑按钮的每一行:

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

This open new window with edit form. 这个打开的新窗口带有编辑表单。 After all changes accepted, I must manually refresh whole page to see modification on Grid. 接受所有更改后,我必须手动刷新整个页面以查看Grid上的修改。 My question is: 我的问题是:

How refresh only Grid after modification of any row entry? 如何在修改任何行条目后仅刷新网格? And how save those modifications to database (maybe beanItemContainer could do it)? 如何将这些修改保存到数据库(也许beanItemContainer可以做到)?

使用Vaadin 8,以下工作方式可以在添加或删除行或更改基础数据后刷新网格:

grid.getDataProvider().refreshAll();

It's a bug. 这是一个错误。 Grid doesn't update itself after changes were done in underlying container nor has any reasonable method to refresh. 在底层容器中进行更改后,Grid不会自行更新,也没有任何合理的刷新方法。 There are several hacks around this issue ie 围绕这个问题有几个黑客,即

grid.clearSortOrder();

or 要么

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

SSCCE: 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();
}

Possible duplicate Update Grid with a fresh set of data, in Vaadin 7.4 app 在Vaadin 7.4应用程序中,可能重复更新网格,其中包含一组新数据

从Vaadin 7.7.4开始, refreshRows(Object ... itemIds)有一个refreshRows(Object ... itemIds)和一个refreshAllRows()方法: httpsrefreshAllRows()

I had to explicitly call grid.setItems() after each call to saveListener event to make my Vaadin 8.3 Grid refresh data inside the grid. 我必须在每次调用saveListener事件后显式调用 grid.setItems() ,以使我的Vaadin 8.3 Grid刷新网格内的数据。 It's strange that the visual grid state does not reflect edited values. 很奇怪的是,视觉网格状态反映编辑的值。

Scala implementation: 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)
  })
}

There is a way to solve the problem much better: 有一种方法可以更好地解决问题:

You have to get the BeanItem from the container and pass this to your editor window. 您必须从容器中获取BeanItem并将其传递给编辑器窗口。 There you can change the bean itself by asscessing it hrough the BeanItem s Properies . 在那里你可以通过BeanItemProperies来解决它本身。 This is a very manual work so I use instead always databindg of FieldGroup - just call bind (field, "propertyName"); 这是一个非常手工的工作,所以我总是使用FieldGroup - 只需调用bind (field,“propertyName”); where propertyName is the getter method without get and non capital letter. 其中propertyName是没有get和非大写字母的getter方法。

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

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