Vaadin Grid 中的可点击图标在每次调用 setItems() 后多次执行代码

Rob*_*uch 2 vaadin vaadin-grid vaadin-flow vaadin14

在我的 Vaadin 应用程序中,我显示了Grid带有自定义类的项目Transaction。该网格的行为应如下所示:

  1. 它应包含一个“操作”列,该列又应包含一个或多个图标。为了简单起见,我们只考虑一个图标。
  2. 这些图标中的每一个都应该是可点击的。
  3. 单击图标,将使用Transaction当前行的项目执行一些代码。在这里,一个简单的Notification.show().

我设法用以下代码来实现这一点:

private final Grid<Transaction> transactionGrid = new Grid<>(Transaction.class, false);
transactionGrid.setItems(transactionService.getItems());

transactionGrid.addColumn(getActionsRenderer()).setHeader("Actions").setAutoWidth(true);

private ComponentRenderer<Icon, Transaction> getActionsRenderer() {
    final Icon replyIcon = new Icon(VaadinIcon.ENVELOPE);
    return new ComponentRenderer<>(transaction -> {
        replyIcon.addClickListener(event -> Notification.show(transaction.getOrderNumber()));
        return replyIcon;
    });
}
Run Code Online (Sandbox Code Playgroud)

单击该图标会显示一条带有交易的通知orderNumber。问题如下:

该应用程序还提供了一个“重新加载”按钮,它的作用与此类似:

refreshIcon.addClickListener(event -> {
    final List<Transaction> transactions = transactionService.getItems();
    transactionGrid.setItems(transactions);
});
Run Code Online (Sandbox Code Playgroud)

单击刷新图标后,单击该行replyIcon会显示相同数据的三个通知。下次刷新后,它会显示五个,然后是七个,依此类推。

因此,看起来好像每次刷新都会添加两个任何“组件”,它们都注册相同的点击侦听器。调试时,我可以看到有多个ClickEvent,eventBus但我不知道它们来自哪里。

在此输入图像描述

Rob*_*uch 5

我的错误是在声明之外定义图标new ComponentRenderer<>。将代码更改为这样似乎可以解决问题:

private ComponentRenderer<Icon, Transaction> getActionsRenderer() {
    return new ComponentRenderer<>(transaction -> {
        final Icon replyIcon = new Icon(VaadinIcon.ENVELOPE);
        replyIcon.addClickListener(event -> Notification.show(transaction.getOrderNumber()));
        return replyIcon;
    });
}
Run Code Online (Sandbox Code Playgroud)