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, вы можете создать @UIScoped и добавьте свои собственные поля, хранящие состояние, относящееся к текущему окну / вкладке браузера. Компонент будет доступен, покаUI настоящее.

Другие вопросы по тегам