【问题标题】:Vaadin 14 LTS Grid refresh after adding new data not working添加新数据后 Vaadin 14 LTS Grid 刷新不起作用
【发布时间】:2021-07-03 02:01:17
【问题描述】:

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

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

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 添加新数据时,网格不会刷新。有什么想法吗?

【问题讨论】:

    标签: java jakarta-ee vaadin java-ee-8 vaadin-grid


    【解决方案1】:

    要使其与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()
    ));
    

    【讨论】:

    • 感谢您的回答。我正在尝试再次设置项目并使用惰性数据提供程序,但是当我使用它时,我的过滤器不起作用,我现在不知道为什么。查看我新编辑的帖子。
    猜你喜欢
    • 1970-01-01
    • 2020-04-23
    • 2016-10-02
    • 2015-06-10
    • 2022-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    相关资源
    最近更新 更多