【问题标题】:Sending parameters to UI and updating UI with Java/Vaadin向 UI 发送参数并使用 Java/Vaadin 更新 UI
【发布时间】:2019-10-16 06:22:11
【问题描述】:

初始情况如下图所示。我有一个创建对话框的主 UI。在此对话框中会生成一些属性。我想在按钮单击时将属性传输到主 UI,然后关闭对话框。然后我想刷新 UI,以便 UI 使用新的属性/参数进行更新。

关闭对话框的工作方式如下:

this.getParent().ifPresent(parent -> {
            if(parent instanceof Dialog)
            {
                ((Dialog)parent).close();
            }
        });

但现在我不知道如何将属性传输到主 UI 并在之后刷新它。

为了更好的想象,我将解释一个用例。 在对话框中我得到一个特定的数字(´int i = 2`)。在 UI 中有一个创建选项卡的方法。我想要和我说的一样多的标签。所以我需要在 UI 类中声明 i 才能成功执行该方法。

创建标签的代码: 构造函数(MainView):

final Tabs tabs = this.createTabs();
    this.add(this.div, tabs);
    tabs.addSelectedChangeListener(e -> {
        this.div.removeAll();
        this.div.add(this.tabComponentMap.get(e.getSelectedTab()));
    });
    this.div.add(this.tabComponentMap.get(tabs.getSelectedTab()));

方法创建标签:

private Tabs createTabs()
{
    for(int i = 0; i <= h; i++)
    {
        if(i == 0)
        {
            this.tabComponentMap.put(new Tab("Tab" + i), new SubView1());
        }
        else
        {
            this.tabComponentMap.put(new Tab("Tab" + i), new SubView2());
        }
    }
    return new Tabs(this.tabComponentMap.keySet().toArray(new Tab[]{}));
}

h 是我从对话框中获得的属性。

【问题讨论】:

  • 如果我只使用UI.getCurrent().navigate("");,属性会分别消失,不会转移到 UI。
  • 您是否考虑将值存储在父组件范围内可用的变量中?这就是我们通常的做法。
  • @Ben 我如何将它存储在对话框的父组件中?能举个例子吗?
  • 你检查过这个问题吗? Vaadin (Flow): Navigating to destination with a shared object 您可以通过 VaadinSession 或导航路线传递您需要的信息。这似乎是您正在寻找的东西
  • 另一种方法是将您的视图传递到对话框中,因此在关闭对话框之前您可以调用myView.setValuesFromDialog(amountOfTabs);。不需要刷新用户界面,也不需要导航。

标签: java vaadin


【解决方案1】:

有不同的方法可以做到这一点。我会(并且实际上会)解决这个问题的方法是将视图传递给对话框,因此对话框可以调用视图的方法来更新某些值。

@Route("dialog-test")
public class MyViewWithDialog extends VerticalLayout {
    private int tabsAmount = 0;
    public MyViewWithDialog(){
        TabsAmountDialog dialog = new TabsAmountDialog(this);
        Button openTabsAmountDialog = new Button("Open Dialog", click -> dialog.open());
        // adding of components omitted
    }

    public void setTabsAmount(int tabsAmount){
        this.tabsAmount = tabsAmount;
        // TODO: update tabs accordingly
    }
}
public class TabsAmountDialog extends Dialog {
    public TabsAmountDialog(MyViewWithDialog view){
        NumberField tabsAmountInput = new NumberField(); 
        Button confirmBtn = new Button("Confirm", click -> {
            // update tabsAmount value in view
            view.setTabsAmount(tabsAmountInput.getValue()); // converters omitted 

            // close Dialog
            this.close();
        });

        // adding of components omitted
    }
}

编辑:从您的评论中,我可以看到您没有直接扩展 Dialog 的组件,而是添加了另一个 View 作为新 Dialog 的组件。这也有效。在您的情况下,您需要做的就是

Dialog dialog = new Dialog(); 
dialog.add(new DialogView(this)); // pass this view into the other view, and do the same as I did there 
dialog.open();

【讨论】:

  • 谢谢你,这似乎有效。但是如何更新主视图,以便再次执行创建选项卡的方法?
  • 我尝试通过this.getParent().get().getUI().get().getPage().reload();重新加载页面,但标签数量没有更新
  • 这将落入MyViewWithDialog::setTabsAmount 中的TODO: update tabs accordingly。我不知道你是如何实现你的标签的,即使我知道这会打破这个问题的范围。但是你显然需要更新或重新创建你的标签,仅仅重新加载一个视图永远不会神奇地改变事情。有一件事是肯定的,您不需要重新加载页面。
  • 那么你能告诉我如果我想在某个时刻更新 vaadin 组件,我需要寻找什么吗?
  • 我不确定我是否理解。除了更新所述组件外,您无需执行任何操作。只要在某种事件侦听器中进行更改,更改就会立即应用并显示在浏览器中。但是,如果更改是在后台线程中进行的(在您的情况下,它不是!)那么您需要在ui.access() 块内进行更改并启用@Push 模式。为了说明我的观点,您可以尝试在按钮单击侦听器中更改 Label 的文本。您会看到单击按钮后会立即显示此更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
  • 1970-01-01
  • 2019-09-05
  • 2014-10-01
  • 2017-01-21
  • 1970-01-01
相关资源
最近更新 更多