Vaadin:如何获取 URL 参数?

Vaadin: How can I get URL parameters?

我一直在尝试使用 Vaadin 从我的项目中的 url 获取参数,但它似乎无法正常运行。我按照 vaadin 文档中的说明进行操作,但未正确设置参数。 routerlink 使用参数(例如 localhost:8080/banner/g50)正确导航,但在新视图中它没有正确设置变量。

@Route(value = "banner", layout = MainLayout.class)
@PageTitle("Banner")
public class BannerView extends VerticalLayout implements HasUrlParameter<String> {
       private String ID;
       ...
    @Override
    public void setParameter(BeforeEvent event,String parameter) {
        ID = parameter;
    }
    //this is in my other view 
    String pathVariable = getID();
    RouterLink routerLink = new RouterLink("Link to data", BannerView.class, pathVariable);

编辑: 这是我的构造函数

public BannerView(BannerService bannerService, GameService gameService) {
        this.bannerService = bannerService;
        this.gameService = gameService;
        addClassName("banner-view");
        setDefaultHorizontalComponentAlignment(Alignment.CENTER);
        //span just added for testing purposes
        Span test = new Span("+" + ID + "+");
        add(getBannerCount(), getDataChart(), getAverageStats(), test);
    }

ID 用于我用来添加组件的三种方法(return 跨度、垂直布局和图表)。我尝试将我的添加组件放在一个带有点击侦听器事件的按钮中,这样我就可以在构造函数完成 运行 之后通过单击按钮来添加组件,正如评论所建议的那样,但这导致了异常:java.io.InvalidClassException:本地 class 不兼容:。添加在构造函数中正确 运行,带有用于测试的硬编码 ID

这只是我的猜测,但是您是否在构造函数中使用了 ID 值?

setParameter 方法 is/will 在构造函数之后调用,因此值将分别为 null 。正如在评论中已经注意到的那样,您的代码似乎是正确的(除了将 RouterLink 转换为 Router,但这是一个编译错误),所以您能否添加有关如何以及在何处使用 ID 的更多详细信息:)

编辑


您确实在使用构造函数中的 ID 值,因此将逻辑移至一个单独的方法,该方法将从 setParameter 中调用。无需使用 Push(异步更新一个 UI)

类似于:

    @Override
    public void setParameter(BeforeEvent event,String parameter) {
        ID = parameter;
        addSpanToUI();

    }

     private void addSpanToUI() {
        Span test = new Span("+" + ID + "+");
        //Assuming based on your comment that each method depends on id
        add(getBannerCount(), getDataChart(), getAverageStats(), test);

     }

     public BannerView(BannerService bannerService, GameService gameService) {
        this.bannerService = bannerService;
        this.gameService = gameService;
        addClassName("banner-view");
        setDefaultHorizontalComponentAlignment(Alignment.CENTER);
    }

您获取参数的方式是正确的。

调用构造函数后显示html页面

setParameter方法在构造函数之后调用,因此确实设置了ID字段,但是ui没有随着变化而更新。

为了对组件执行 ui 更新,您应该调用 UI.getCurrent().access():

@Override
public void setParameter(BeforeEvent beforeEvent, String parameter) {
    this.ID = parameter;
    UI.getCurrent().access(() -> {
        Span test = new Span(ID);
        add(test);
    });
}

确保不要在 access() 中 运行 长时间 运行ning 操作,因为这会使浏览器无响应!

附带说明一下,如果您需要围绕视图传递数据,那么我建议您使用 ComponentUtil 事件总线。因为 url 参数将以 ascii 编码的字符串形式出现,也因为它允许共享对象

您可以通过这种方式从任何视图设置数据

String greetingFromView1 = "Hello world";    
ComponentUtil.setData(UI.getCurrent(), "greeting", greetingFromView1);

之后就可以通过这种方式获取任意视图的数据了

String greetingFromView2 = (String)ComponentUtil.getData(UI.getCurrent(), "greeting");