【问题标题】:How to edit two comboboxes with listeners in a Vaadin 8 grid editor如何在 Vaadin 8 网格编辑器中使用侦听器编辑两个组合框
【发布时间】:2018-04-05 05:01:26
【问题描述】:

我的可编辑Grid 中有两个ComboBoxes,其中第二个ComboBox 基于第一个。因此,例如,您将拥有汽车制造商,然后是汽车模型。当您更改 make 组合框时,模型组合框也会相应更改。

考虑到这一点,我有:

ComboBox<String> makeComboBox = new ComboBox<String>();
ComboBox<String> modelComboBox = new ComboBox<String>();

具体来说:

grid.addColumn(CarRental::getPerson)
    .setEditorBinding(binder.forField(personComboxBox).bind(CarRental::getPerson, CarRental::setPerson));
grid.addColumn(CarRental::getMake)
    .setEditorBinding(binder.forField(makeComboxBox).bind(CarRental::getMake, CarRental::setMake));
grid.addColumn(CarRental::getModel)
    .setEditorBinding(binder.forField(modelComboxBox).bind(CarRental::getModel, CarRental::setModel));

这里的关键是,如果 makeComboBox 改变了,我希望 modelComboBox 也改变。换句话说,如果您选择 Honda,那么我希望模型 ComboBox 更改为 Fit、Civic、Accord 等。为此我添加了一个SelectionListener(但也可以是ValueChangeListener,没关系,效果还是一样的)。

特别是我有:

makeComboBox.addSelectionListener(event -> 
{
    modelComboBox.clear();
    modelComboBox.setItems(getModelsBasedOnMake(makeComboBox.getValue()));
    // Assuming someone has just edited the make value, 
    // say changed from Toyota to Honda, then I want the model selected to be empty 
});

因为 ComboBox 可以不同,所以我是 ve added some logic to update the components on theOpenListenerfor the Grid Editor。具体来说:

grid.getEditor().addOpenListener(open ->
{
   ...
   CarRental selectedCarRental = (CarRental)event.getBean();
   makeComboBox.setItems(makeList);
   modelComboBox.setItems(getModelsBasedOnMake(carRental.getMake()));
});

这里的问题是modelComBoxbox 倾向于被取消选择,因为如果你查看它,因为存在冲突,所以无法保证它会是哪个值。

我查看了暂时禁用 selectionListener ,但所有删除侦听器都已被 Vaadin 8 弃用。因此,我如何设置网格以便能够在网格中编辑汽车品牌和型号?

【问题讨论】:

  • 当使用相关的 ValueChangeListeners 更新许多字段时,我一直在使用成员字段 isLoading 在其他侦听器中进行检查,以便他们知道什么时候不应该做任何事情。这种方法对您也有帮助吗?
  • "但是所有删除侦听器都已被 Vaadin 8 弃用" -> add*Listener 方法返回一个类型为 Registration 的对象,该对象具有一个方法 remove。这就是你的意思吗?

标签: java vaadin vaadin8 vaadin-grid


【解决方案1】:

我通过一个简单的示例进行了尝试。对我来说看起来不错。确切的问题是什么? (我真的不明白您的句子“因为如果您查看它,则无法保证它将是哪个值,因为存在冲突。”)

@SpringUI
public class VaadinUI extends UI {

    @Override
    protected void init(VaadinRequest request) {
        VerticalLayout layout = new VerticalLayout();

        ComboBox<String> cmb1 = new ComboBox<>();
        ComboBox<String> cmb2 = new ComboBox<>();
        cmb1.setItems("1", "2", "3");
        cmb1.addSelectionListener(event -> {
            cmb2.clear();
            cmb2.setItems(getCmb2Content(event.getValue()));
        });

        Grid<MyBean> grid = new Grid<>();
        grid.setWidth("800px");
        grid.setHeightByRows(10);
        grid.addColumn(System::identityHashCode).setCaption("ID");
        grid.addColumn(MyBean::getProp1).setCaption("Prop 1")
                .setEditorBinding(grid.getEditor().getBinder().forField(cmb1).bind(MyBean::getProp1, MyBean::setProp1));
        grid.addColumn(MyBean::getProp2).setCaption("Prop 2")
                .setEditorBinding(grid.getEditor().getBinder().forField(cmb2).bind(MyBean::getProp2, MyBean::setProp2));
        grid.setItems(new MyBean(), new MyBean(), new MyBean());
        grid.getEditor().setEnabled(true);

        layout.addComponent(grid);

        setContent(layout);
    }

    private List<String> getCmb2Content(String cmb1Content) {
        return Arrays.asList(cmb1Content + "1", cmb1Content + "2", cmb1Content + "3");
    }

}

public static class MyBean {

    private String prop1;
    private String prop2;

    public String getProp1() {
        return prop1;
    }

    public void setProp1(String prop1) {
        this.prop1 = prop1;
    }

    public String getProp2() {
        return prop2;
    }

    public void setProp2(String prop2) {
        this.prop2 = prop2;
    }
}

【讨论】:

  • 如果侦听器中的部分逻辑是根据 cmb1 的值设置 cmb2,那么这将失败,因为绑定器将为 cmb1 设置值,然后为 cmb2 设置值。但是,如果您对 cmb2 的值是一个覆盖值怎么办?例如,假设您的桌子用于汽车租赁。这些列是 customerName、make 和 model。 Your combobox on customerName states that when John is selected you want the make and model to be Honda Civic.但是,在您的表格数据中,您的条目是驾驶本田雅阁的约翰(他想要的东西与往常不同)。
  • 在这种情况下,您希望品牌和型号组合框显示什么? binder 将要选择 Honda Accord,而组合框侦听器将要选择 Honda Civic。您基本上需要一种方法来防止组合框侦听器被激活,直到编辑器准备好...
  • IMO 网格中显示的数据必须与基础数据匹配。因此,如果您已将数据从数据源(例如数据库)提取到内存,那么您可以轻松地通过 UI 编辑内存中的数据并按需将数据保存到数据源。
猜你喜欢
  • 2017-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多