Vaadin Flow: навигация не работает (?) При использовании SplitLayout и @ParentLayout

[EDIT] Решение в конце вопроса [/EDIT]

контекст

В настоящее время я борюсь за реализацию Component который основан на SplitLayout это выглядит так:

Идея заключалась в том, что макет с class="outer" (выделенная строка) будет заполнителем для контента, который должен был быть загружен, когда пользователь выбирает строку в Grid,

"outer"-Layout был добавлен в SplitLayout рядом с сеткой и поэтому помечены slot='secondary',

Другой класс ссылается на 'outer'-Layout с @Route(value = "details", layout = OuterLayout.class)

Нажав на запись Grid страница переходит к "grid/details",


Проблема:

Я ожидал, что Ваадин поместит содержимое аннотированного класса в 'outer'-Layout но вместо этого он добавляет новую запись рядом с ним: Если я уберу первый 'outer'-Layout Ваадин отмечает второй как slot='secondary' и его содержание появляется: Его даже обновление в соответствии с выбранным в настоящее время Гридентри...


Источники:

Splitlayout

@Route(value = "grid", layout = ContentLayout.class)
@ParentLayout(ContentLayout.class)
public class MySplitLayout extends SplitLayout implements RouterLayout {
    private MyGrid grid;
    private MyDetailOuterLayout detailOuterLayout;

    public MySplitLayout() {
        setSizeFull();

        grid = new MyGrid();
        detailOuterLayout = new MyDetailOuterLayout();

        addToPrimary(grid);
        addToSecondary(detailOuterLayout);
    }
}

внешний

@ParentLayout(MySplitLayout.class)
public class MyDetailOuterLayout extends FlexLayout implements RouterLayout{

    public MyDetailOuterLayout() {
        setClassName("outer");
    }
}

внутренний

@Route(value = "grid/details", layout = MyDetailOuterLayout.class)
public class MyDetailLayout extends FlexLayout 
        implements HasUrlParameter<Integer>, BeforeEnterObserver
{
    public MonitorDetailLayout() {
        setClassName("inner");

        /* define data via URL*/
    }
}

Я неправильно понял концепцию жизненного цикла?

заранее спасибо


Решение

По предложению Тату Лунда я изменил реализацию по умолчанию RouterLayout как это:

@Route(value = "grid", layout = ContentLayout.class)
@ParentLayout(ContentLayout.class)
public class MySplitLayout extends SplitLayout implements RouterLayout {
    private MyGrid grid;
    private MyDetailOuterLayout detailOuterLayout;

    public MySplitLayout() {
        setSizeFull();

        grid = new MyGrid();
        detailOuterLayout = new MyDetailOuterLayout();

        addToPrimary(grid);
        addToSecondary(detailOuterLayout);
    }

    @Override
    public void showRouterLayoutContent(HasElement content) {
        if (content != null) {
            Element rootElement = getElement();
            rootElement.removeChild(detailOuterLayout.getElement()); // aka the secondary Element
            rootElement.appendChild(Objects.requireNonNull(content.getElement()));
        }
    }

}

1 ответ

Решение

Идея с RouterLayout использовать в случаях, как у вас есть, вы должны переопределить showRouterLayoutContent(..) метод. Когда происходит навигация, вызывается этот метод, и он помещает контент, к которому вы перешли, в макет. Так что в вашем случае я предполагаю, что вам нужна цель маршрута, которая оборачивает Grid.

Таким образом, шаблон такой: например, в вашем основном макете вам нужно иметь держатель контента, здесь это Div, но это может быть что угодно (например, SplitLayout или что-то еще)

public class MainLayout extends VerticalLayout implements RouterLayout {
   private Div childWrapper = new Div();

   @Override
   public void showRouterLayoutContent(HasElement content) {
       childWrapper.getElement().appendChild(content.getElement());
   }
}

Также обратите внимание, если вы используете @Route(value="..", layout = ParentLayout.class) аннотации, вы не должны использовать @ParentLayout(ParentLayout.class) вместе с этим. Вам нужно использовать @ParentLayout только для классов, которые не являются целями Route.

Здесь есть дополнительная информация: https://vaadin.com/docs/v12/flow/routing/tutorial-router-layout.html и здесь: https://vaadin.com/tutorials/nested-layouts-in-flow

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