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

Vaadin 14 LTS Grid refresh after adding new data not working

我试图在向其中添加一行后刷新网格,但它不起作用。这是我的 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
});

对于我正在使用的服务,这里是帐户服务代码:

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

已编辑:添加注册帐户。

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

要使其与 ListDataProvider 一起使用,您必须修改基础列表(add/remove 项)。

现在您调用 refreshAll(),它只是再次读取您传递的列表,因为它仍然包含相同的项目,所以没有任何变化。它不知道再次从您的服务中获取项目。

我能想到的解决办法有几个:

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

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

如果您的 accountServices.registerAccount 方法 returns 新保存的项目,您可能想要添加那个。

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