データベースからのデータを使用して単純なグリッドを作成します。
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()));
これにより、編集フォームで新しいウィンドウが開きます。すべての変更を受け入れた後、グリッドでの変更を確認するには、ページ全体を手動で更新する必要があります。私の質問は:
行エントリを変更した後、グリッドのみを更新するにはどうすればよいですか?そして、それらの変更をデータベースにどのように保存しますか(おそらくbeanItemContainerがそれを行うことができます)?
バグです。基になるコンテナで変更が行われた後、グリッドはそれ自体を更新せず、更新するための合理的な方法もありません。この問題にはいくつかのハックがあります。
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();
}
Vaadin 8では、行が追加または削除された後、または基になるデータが変更された後に、グリッドが次のように更新されます。
grid.getDataProvider().refreshAll();
Vaadin 7.7.4以降、グリッドにはrefreshRows(Object ... itemIds)
メソッドとrefreshAllRows()
メソッドがあります: https://dev.vaadin.com/ticket/16765
Vaadin 8.3グリッドでグリッド内のデータを更新するには、saveListener
イベントを呼び出すたびに明示的に呼び出すgrid.setItems()
を実行する必要がありました。視覚的なグリッド状態がnot編集された値を反映するのは奇妙です。
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)
})
}
問題をよりよく解決する方法があります:
BeanItem
をコンテナーから取得して、エディターウィンドウに渡す必要があります。そこで、BeanItem
s Properies
を介してアクセスすることにより、Bean自体を変更できます。これは非常に手動の作業なので、代わりに常にFieldGroup
のdatabindgを使用します-bind
(field、 "propertyName");を呼び出すだけです。ここで、propertyNameは、getと大文字以外の文字を含まないgetterメソッドです。