Vaadin 14 LTS添加新数据后网格刷新不起作用



我试图在添加一行后刷新网格,但它不起作用。这是我的UI代码上的事件侦听器:编辑的完整代码。

Grid<TransactionModel> transactionData = new Grid<>(TransactionModel.class);
try {
// transactionData.setItems(transactionServices.getTransactionTable());
List<TransactionModel> transactionList = transactionServices.getTransactionTable();
ListDataProvider<TransactionModel> transactionDataProvider = new ListDataProvider<>(transactionList);
transactionData.setDataProvider(transactionDataProvider);
transactionData.setColumns("id", "transactionTimestamp", "srcAccountId", "dstAccountId", "amount");
Grid.Column<TransactionModel> idColumn = transactionData.getColumnByKey("id");
Grid.Column<TransactionModel> srcAccountIdColumn = transactionData.getColumnByKey("srcAccountId");
Grid.Column<TransactionModel> dstAccountIdColumn = transactionData.getColumnByKey("dstAccountId");
HeaderRow filterRow2 = transactionData.appendHeaderRow();
TransactionFilterModel transactionFilterModel = new TransactionFilterModel();
transactionDataProvider.setFilter(transaction -> transactionFilterModel.find(transaction));
// Filter srcAccountId
TextField idField = new TextField();
idField.addValueChangeListener(event -> {
transactionFilterModel.setId(event.getValue());
transactionDataProvider.refreshAll();
});
idField.setValueChangeMode(ValueChangeMode.EAGER);
filterRow2.getCell(idColumn).setComponent(idField);
idField.setSizeFull();
idField.getElement().setAttribute("focus-terget", "");
// Filter srcAccountId
TextField srcAccountIdField = new TextField();
srcAccountIdField.addValueChangeListener(event -> {
transactionFilterModel.setSrcAccountId(event.getValue());
transactionDataProvider.refreshAll();
});
srcAccountIdField.setValueChangeMode(ValueChangeMode.EAGER);
filterRow2.getCell(srcAccountIdColumn).setComponent(srcAccountIdField);
srcAccountIdField.setSizeFull();
srcAccountIdField.getElement().setAttribute("focus-terget", "");
// Filter dstAccountId
TextField dstAccountIdField = new TextField();
dstAccountIdField.addValueChangeListener(event -> {
transactionFilterModel.setDstAccountId(event.getValue());
transactionDataProvider.refreshAll();
});
dstAccountIdField.setValueChangeMode(ValueChangeMode.EAGER);
filterRow2.getCell(dstAccountIdColumn).setComponent(dstAccountIdField);
dstAccountIdField.setSizeFull();
dstAccountIdField.getElement().setAttribute("focus-terget", "");
transactionData.setWidth("50%");
} catch (JsonProcessingException | EndpointException ex) {
Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ex);
}
// Event Listener
submitButton.addClickListener(e -> {
System.out.println("Submitted !");
AccountModel submittedModel = new AccountModel();
if (accountModelBinder.writeBeanIfValid(submittedModel)) {
try {
accountServices.registerAccount(submittedModel);
accountIdTextField.clear();
nameTextField.clear();
addressTextField.clear();
birthDateDatePicker.clear();
allowNegativeBalanceButtonGroup.clear(); 
} catch (EndpointException | JsonProcessingException ez) {
Logger.getLogger(MainView.class.getName()).log(Level.SEVERE, null, ez);
}
}
accountData.getDataProvider().refreshAll(); // <- REFRESH
});

对于我使用rest的服务,这里是账户服务代码:

public List<AccountModel> getAccountTable() throws JsonProcessingException, EndpointException {
List<AccountModel> datalog = new JsonResponseReader(restMockvaEndpoint.send(new EndpointRequestBuilder()
.method("GET")
.resource("/account")
.build()
)).getContentTable(AccountModel.class).getData();
return datalog;
}
public AccountModel registerAccount(AccountModel accountModel) throws JsonProcessingException, EndpointException{
AccountModel account = new JsonResponseReader(restMockvaEndpoint.send(new EndpointRequestBuilder()
.method("POST")
.content(Json.getWriter().writeValueAsBytes(accountModel), MediaType.APPLICATION_JSON)
.resource("/account")
.build())).getContentObject(AccountModel.class);
return account; 
}

编辑:添加registerAccount。

问题是,当我单击submitButton添加新数据时,网格不会刷新。有什么想法吗?

要使用ListDataProvider,您必须修改底层列表(添加/删除项(。

现在您调用了refreshAll(),它只是再次读取您传递的列表,并且由于它仍然包含相同的项目,所以没有任何更改。它不知道如何再次从您的服务中提取项目。

我能想到几个解决方案:

1.手动将新项目添加到列表中(然后它将出现在网格的末尾(:

accountList.add(submittedModel);
...
// This instructs the grid to read the list again
accountData.getDataProvider().refreshAll();

如果accountServices.registerAccount方法返回新保存的项,则可能需要添加该项。

2.重新设置项目

您可以再次获取项目并设置新的数据提供程序。那么您可以使用setItems(...),它在引擎盖下使用ListDataProvider

// Run this both when first creating the grid, and again after the new item is saved.
// This time you don't need to call refreshAll()
List<AccountModel> accountList = accountServices.getAccountTable();
accountData.setItems(accountList);

3.使用惰性数据提供程序

当您使用惰性数据提供程序时,例如从回调,那么调用refreshAll()会再次执行这些回调以获取新项。

在这种情况下,您需要实现所需的服务方法,如果您需要排序或筛选,则需要做更多的工作。

this.setDataProvider(DataProvider.fromCallbacks(
query -> myAccountService.getAccounts(query.getOffset(), query.getLimit()).stream(),
query -> myAccountService.countAccounts()
));

最新更新