显示复杂 objects 列表并发出事件 int vaadin 14 的最佳方式
Best way to show a list of complex objects and emit event int vaadin 14
例如,我有一个订单,我的用户可以添加一个商店,并且在每个商店中有很多物品:
Amazon
- cup - $ 1
- notebook - $ 3
- $ 4 Ebay
- bike - $ 10
- boat - $ 13
- $ 23
Total order: $ 27 [Button to send the order]
在我的项目中,我有 3 个组件:
CartView -(显示订单总额和一个按钮)
- StoreView(显示商店名称和总数)
---StoreitemView(显示项目和要删除的按钮)
抛开疑惑:
1 - 显示列表的最佳方式是使用单行网格?有些像这样:
Grid<StoreView> myGrid = new Grid();
myGrid.addComponentColumn(this::createStoreView).setAutoWidth(true);
或者最好像这样使用 for:
Div myDiv = new Div();
for(Store store in StoreList){
muDiv.add(new StoreView(store);
}
2 - 如何将事件传递给 parent?所以当我的用户在 StoreItemView 上单击一个按钮时,我需要将该事件发送到我的 CartView(传递到 StorView,然后转到 CarView 以更新值并重新创建购物车)
谢谢
布局
布局取决于您期望的商店和商品数量。如果数量很少,循环并添加组件是一个不错的方法。
如果您有很多项目,使用带有一列的 Grid
是更好的方法,因为不会同时呈现所有项目。更好的方法可能是 IronList
,或者自 Vaadin 21 以来 VirtualList.
如果您的视图很复杂,包含很多组件,最好使用 TemplateRenderer
而不是 ComponentRenderer
。如果在 HTML 而不是 Java 中编写视图不是你的菜,你可以继续使用 ComponentRenderer
,尤其是在性能似乎不错的情况下。
如果每个商店的商品很多,您也可以考虑在商店内为商店商品创建一个虚拟列表。特别是如果只有几家商店。
活动
这里没有正确答案。看起来你的 StoreView
和 StoreItemView
是紧密耦合的,所以通信也可以是紧密耦合的。例如,StoreItemView
可以直接使用 getRemoveButton()
方法公开按钮。
我会使用 ComponentEvent
作为删除事件,类似于下面的代码。您创建 StoreItemView
的逻辑会有所不同,您可以在 StoreView
中添加一个方法来添加事件侦听器。您可能还想向事件中添加一些数据。
public class StoreView extends HorizontalLayout {
public StoreView() {
// Create your store items as you see fit
StoreItemView storeItemView = new StoreItemView();
storeItemView.getRemoveButton().addClickListener(e -> {
remove(storeItemView);
fireEvent(new StoreItemRemovedEvent(storeItemView));
});
add(storeItemView);
}
public static class StoreItemRemovedEvent extends
ComponentEvent<StoreItemView> {
public StoreItemRemovedEvent(StoreItemView source) {
super(source, false);
}
}
}
public class CartView extends VerticalLayout {
public CartView() {
StoreView storeView = new StoreView();
ComponentUtil.addListener(storeView, StoreView.StoreItemRemovedEvent.class, e ->
Notification.show("Store item removed"));
add(storeView);
}
}
例如,我有一个订单,我的用户可以添加一个商店,并且在每个商店中有很多物品:
Amazon
- cup - $ 1
- notebook - $ 3
- $ 4 Ebay
- bike - $ 10
- boat - $ 13
- $ 23
Total order: $ 27 [Button to send the order]
在我的项目中,我有 3 个组件:
CartView -(显示订单总额和一个按钮) - StoreView(显示商店名称和总数) ---StoreitemView(显示项目和要删除的按钮)
抛开疑惑: 1 - 显示列表的最佳方式是使用单行网格?有些像这样:
Grid<StoreView> myGrid = new Grid();
myGrid.addComponentColumn(this::createStoreView).setAutoWidth(true);
或者最好像这样使用 for:
Div myDiv = new Div();
for(Store store in StoreList){
muDiv.add(new StoreView(store);
}
2 - 如何将事件传递给 parent?所以当我的用户在 StoreItemView 上单击一个按钮时,我需要将该事件发送到我的 CartView(传递到 StorView,然后转到 CarView 以更新值并重新创建购物车)
谢谢
布局
布局取决于您期望的商店和商品数量。如果数量很少,循环并添加组件是一个不错的方法。
如果您有很多项目,使用带有一列的 Grid
是更好的方法,因为不会同时呈现所有项目。更好的方法可能是 IronList
,或者自 Vaadin 21 以来 VirtualList.
如果您的视图很复杂,包含很多组件,最好使用 TemplateRenderer
而不是 ComponentRenderer
。如果在 HTML 而不是 Java 中编写视图不是你的菜,你可以继续使用 ComponentRenderer
,尤其是在性能似乎不错的情况下。
如果每个商店的商品很多,您也可以考虑在商店内为商店商品创建一个虚拟列表。特别是如果只有几家商店。
活动
这里没有正确答案。看起来你的 StoreView
和 StoreItemView
是紧密耦合的,所以通信也可以是紧密耦合的。例如,StoreItemView
可以直接使用 getRemoveButton()
方法公开按钮。
我会使用 ComponentEvent
作为删除事件,类似于下面的代码。您创建 StoreItemView
的逻辑会有所不同,您可以在 StoreView
中添加一个方法来添加事件侦听器。您可能还想向事件中添加一些数据。
public class StoreView extends HorizontalLayout {
public StoreView() {
// Create your store items as you see fit
StoreItemView storeItemView = new StoreItemView();
storeItemView.getRemoveButton().addClickListener(e -> {
remove(storeItemView);
fireEvent(new StoreItemRemovedEvent(storeItemView));
});
add(storeItemView);
}
public static class StoreItemRemovedEvent extends
ComponentEvent<StoreItemView> {
public StoreItemRemovedEvent(StoreItemView source) {
super(source, false);
}
}
}
public class CartView extends VerticalLayout {
public CartView() {
StoreView storeView = new StoreView();
ComponentUtil.addListener(storeView, StoreView.StoreItemRemovedEvent.class, e ->
Notification.show("Store item removed"));
add(storeView);
}
}