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 */
}
}
Изнутри Grid
Я пытался ориентироваться так:
addSelectionListener((event) -> {
event.getFirstSelectedItem().ifPresent(somemodel -> {
getUI().ifPresent(ui -> {
ui.navigate(DetailLayout.class, somemodel);
});
});
});
Но, к сожалению, это поведение не поддерживается Vaadin, даже если его синтаксис в порядке.
Вопрос:
Известен ли вам другой способ пропустить объект во время навигации или я пропустил определенную часть официальной документации?
заранее спасибо
1 ответ
Вместо того, чтобы дать весь somemodel
объект как параметр navigate()
Можете передать ее id
ui.navigate(DetailLayout.class, somemodel.getId());
И в DetailLayout.setParameter()
вы можете загрузить somemodel по его идентификатору
@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?
}
Коллекция ключей и значений
Как обсуждалось в комментариях к другому ответу, если вы не хотите раскрывать значение идентификатора как часть URL-адреса, работайте за кулисами, используя коллекцию значений ключа, предоставленную Vaadin.
На самом деле Vaadin предоставляет коллекции "ключ-значение" на трех уровнях:
- Контекст все
ваше веб-приложение во время выполнения - Сессия
Каждый пользователь - Пользовательский интерфейс
Каждое окно / вкладка веб-браузера, поскольку Vaadin поддерживает многооконные веб-приложения.
Коллекция "ключ-значение" для всего приложения доступна на VaadinContext
, через getAttribute
& setAttribute
методы.
VaadinService.getCurrent().getContext().setAttribute( key , value ) ;
Коллекция ключей и значений для каждого пользователя доступна на VaadinSession
, через getAttribute
& setAttribute
методы.
VaadinSession.getCurrent().setAttribute( key , value ) ;
âž ¥ Коллекция окон / вкладок для каждого браузера (то, что вы хотите для своих нужд в этом вопросе) не так легко доступна. Вы должны пройти косвенный шаг. На ComponentUtil
класс, звонок setData
& getData
методы. Помимо передачи вашего ключа и вашего значения, передайте текущийUI
объект.
Component c = UI.getCurrent() ;
String key = "com.example.acmeapp.selectedProductId" ;
Object value = productId ;
ComponentUtil.setData( c , key , value ) ;
Проголосуйте за мой билет № 6287, просьбу добавить функциюsetAttribute
/getAttribute
методы на UI
класс, чтобы соответствовать тем из VaadinSession
а также VaadinContext
.
Если вы используете Spring с Vaadin Flow, вы можете создать @UIScope
d и добавьте свои собственные поля, хранящие состояние, относящееся к текущему окну / вкладке браузера. Компонент будет доступен, покаUI
настоящее.