问题
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