Vaadin (Flow): Navigating to destination with a shared object

拜拜、爱过 提交于 2020-01-02 08:34:31

问题


Problem:

I currently have a grid that displays content of type SomeModel. When I click an entry of that Grid I would like to navigate to a view that takes an object as its input to display the entries content.

Implementation:

To achive this behaviour I created a DetailLayout like this:

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 */
    }
}

From within the Grid I tried to navigate like this:

addSelectionListener((event) -> {
    event.getFirstSelectedItem().ifPresent(somemodel -> {
        getUI().ifPresent(ui -> {
            ui.navigate(DetailLayout.class, somemodel);
        });
    });
});

But unfortunately this behaviour is not supported by Vaadin even tho its syntax is perfectly fine.


Question:

Do you know of another way to pass an object while navigation or did I miss a certain part of the official documentation documentation ?

Thank you in advance


回答1:


Key-Value collection

As discussed in the comments on the other Answer, if you do not wish to expose the ID value as part of the URL, then work behind the scenes by using the key-value collection provided by Vaadin.

Vaadin actually provides key-value collections at three levels of scope:

  • Context
    Your entire web-app at runtime
  • Session
    Each user
  • UI
    Each web browser window/tab, as Vaadin supports multi-window web-apps

The app-wide key-value collection is available on the VaadinContext, via getAttribute & setAttribute methods.

VaadinService.getCurrent().getContext().setAttribute( key , value ) ;

The per-user key-value collection is available on the VaadinSession, via getAttribute & setAttribute methods.

VaadinSession.getCurrent().setAttribute( key , value ) ;

➥ The per-browser-window/tab collection (what you want for your needs in this Question) is not quite so readily available. You have to go through an indirect step. On the ComponentUtil class, call setData & getData methods. In addition to passing your key and your value, pass the current UI object.

Component c = UI.getCurrent() ;
String key = "com.example.acmeapp.selectedProductId" ;
Object value = productId ;
ComponentUtil.setData( c , key , value ) ;

Please vote for my ticket # 6287, a feature-request to add setAttribute/getAttribute methods on UI class, to match those of VaadinSession and VaadinContext.




回答2:


Instead of giving the whole somemodel object as parameter of navigate(), you can pass its id

ui.navigate(DetailLayout.class, somemodel.getId());

And in the DetailLayout.setParameter() you can load the somemodel by its 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?
}


来源:https://stackoverflow.com/questions/54442697/vaadin-flow-navigating-to-destination-with-a-shared-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!