Vaadin (Flow):使用共享对象导航到目的地

Ger*_*zek 5 java navigation vaadin vaadin-flow

问题:

我目前有一个显示类型内容的网格SomeModel。当我单击其中的一个条目时,Grid我想导航到一个视图,该视图将一个对象作为其输入来显示条目内容。

执行:

为了实现这种行为,我创建了DetailLayout这样的:

public DetailLayout extends FlexLayout implements HasUrlParameter<SomeModel>{
    /* skipped some details */
    @Override
    public void setParameter(BeforeEvent event, Host parameter) {
        /* This is where I expected to be able to handle the object */
    }
}
Run Code Online (Sandbox Code Playgroud)

从内部Grid我尝试像这样导航:

addSelectionListener((event) -> {
    event.getFirstSelectedItem().ifPresent(somemodel -> {
        getUI().ifPresent(ui -> {
            ui.navigate(DetailLayout.class, somemodel);
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

但不幸的是 Vaadin 不支持这种行为,尽管它的语法非常好。


问题:

您是否知道在导航时传递对象的另一种方法,或者我是否错过了官方文档的某个部分?

先感谢您

Bas*_*que 6

键值集合

\n\n

正如另一个 Answer的评论中所讨论的,如果您不希望将 ID 值作为 URL 的一部分公开,则可以使用 Vaadin 提供的键值集合在幕后工作。

\n\n

Vaadin 实际上提供了三个范围级别的键值集合:

\n\n
    \n

  • 在运行时为您的整个 Web 应用程序提供上下文
  • \n
  • 会话
    每个用户
  • \n
  • UI
    每个网络浏览器窗口/选项卡,因为 Vaadin 支持多窗口网络应用程序
  • \n
\n\n

应用程序范围的键值集合可在VaadinContext、 via getAttribute&setAttribute方法上使用。

\n\n
VaadinService.getCurrent().getContext().setAttribute( key , value ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

每个用户的键值集合可在VaadinSession、 via getAttribute&setAttribute方法上使用。

\n\n
VaadinSession.getCurrent().setAttribute( key , value ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x9e\xa5 每个浏览器窗口/选项卡集合(您在这个问题中想要满足您的需求)并不是那么容易获得。你必须经历一个间接的步骤。在类上ComponentUtil,调用setData&getData方法。除了传递您的键和值之外,还传递当前UI对象

\n\n
Component c = UI.getCurrent() ;\nString key = "com.example.acmeapp.selectedProductId" ;\nObject value = productId ;\nComponentUtil.setData( c , key , value ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

请投票给我的票#6287,这是一个在类上添加setAttribute/getAttribute方法的功能请求UI,以匹配 和 的VaadinSession功能VaadinContext

\n


Kas*_*rer 5

您可以传递它的参数,somemodel而不是将整个对象作为 的参数navigate()id

ui.navigate(DetailLayout.class, somemodel.getId());
Run Code Online (Sandbox Code Playgroud)

在 中,DetailLayout.setParameter()您可以通过其 id 加载某个模型

@Override
public void setParameter(BeforeEvent beforeEvent, Long someModelId) {
    if(someModelId == null){
        throw new SomeModelNotFoundException("No SomeModel was provided");
    }

    SomeModel someModel = someModelService.findById(someModelId);
    if(someModel == null){
        throw new SomeModelNotFoundException("There is no SomeModel with id "+someModelId);
    }

    // use someModel here as you wish. probably use it for a binder?
}
Run Code Online (Sandbox Code Playgroud)

  • 还有其他一些方法。如果您使用 CDI 或 Spring,您可以共享该对象,例如 UIScoped bean。另外一种替代方法是将对象共享为会话属性。 (2认同)
  • @gsedlacz不,我会使用 ComponentUtil.setData(UI.getCurrent(),..) 代替,请参阅详细信息:https://vaadin.com/api/platform/12.0.5/com/vaadin/flow/component/ComponentUtil .html#setData-com.vaadin.flow.component.Component-java.lang.String-java.lang.Object- (2认同)