0

[编辑] 问题结束时的解决方案 [/编辑]

语境

我目前很难实现一个Component基于如下所示的SplitLayout在此处输入图像描述

这个想法是带有class="outer"(突出显示的行)的布局将成为内容的占位符,当用户在Grid.

"outer"-Layout添加到SplitLayout网格旁边,因此标有slot='secondary'

另一个类引用'outer'-Layoutwith@Route(value = "details", layout = OuterLayout.class)

通过单击Grid页面的条目导航到"grid/details"


问题:

我希望 Vaadin 将带注释的类的内容放在其中,'outer'-Layout但它会在其旁边添加一个新条目: 在此处输入图像描述 如果我删除第一个'outer'-LayoutVaadin 标记,则第二个标记为slot='secondary'它的内容: 在此处输入图像描述 它甚至根据当前选择的 Gridentry 进行更新。 .


资料来源:

拆分布局

@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*/
    }
}

我误解了生命周期的概念吗?

先感谢您


解决方案

正如 Tatu Lund 所建议的,我修改了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()));
        }
    }

}
4

1 回答 1

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

于 2019-02-01T07:51:09.043 回答