Vaadin - обновить сетку после модификации строки

Я создаю простую сетку с данными из базы данных:

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. Мой вопрос:

Как обновить только Grid после изменения любой записи в строке? И как сохранить эти изменения в базе данных (может быть, beanItemContainer может это сделать)?

5 ответов

Решение

Это ошибка. Сетка не обновляется после внесения изменений в базовый контейнер и не имеет разумного способа обновления. Есть несколько взломов вокруг этой проблемы, т.е.

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

Возможно дублирование Grid обновления со свежим набором данных, в приложении Vaadin 7.4

В Vaadin 8 следующие действия позволяют обновить сетку после добавления или удаления строк или изменения базовых данных:

grid.getDataProvider().refreshAll();

Так как Vaadin 7.7.4 существует refreshRows(Object ... itemIds) и refreshAllRows() метод в сетке: https://dev.vaadin.com/ticket/16765

Есть способ решить проблему намного лучше:

Вы должны получить BeanItem из контейнера и передайте это в окно вашего редактора. Там вы можете изменить сам бин, переместив его через BeanItems Properies, Это очень ручная работа, поэтому я всегда использую FieldGroup - просто позвони bind(поле "propertyName"); где propertyName - метод получения без get и без заглавной буквы.

Я должен был явно позвонить grid.setItems() после каждого звонка saveListener событие, чтобы мой 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)
  })
}
Другие вопросы по тегам