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

[РЕДАКТИРОВАТЬ] Решение в конце вопроса [/ EDIT]

Контекст

В настоящее время я борюсь за реализацию Component, которая основана наSplitLayout, который выглядит следующим образом: enter image description here

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

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

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

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


Проблема:

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


Источники:

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 Ответ

0 голосов
/ 01 февраля 2019

Идея использования 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

...