Load first child view's content initially

Hi,

I have a MainLayout (implementing RouterLayout) annotated with @Route(value = “”). It contains a header label and a NavigationBar (extending Tabs) with two child views (annotated with @Route(value = “child1”, layout = MainLayout.class) and @Route(value = “child2”, layout = MainLayout.class)). When loading the application (with root url) I can see the header label and the navigation. The first tab is selected, but (of course) no content is displayed. I have to explicitly click on the second tab (because the first tab is selected by default, but showing no content) and then click on the first tab, to be able to show the corresponding view of the first tab. What is the right way of displaying the first child view initially? UI.getCurrent().navigateTo(“child1”) has no effect in the MainLayout’s constructor. I also tried letting the MainLayout implement BeforeEnterObserver and use event.rerouteTo(“child1”) which results in an endless loop (which makes sense to me).

I read the Docs and saw that there is a @ParentLayout annotation, but I don’t see how this would help me display one of the child views initially.

An additional question: If I use a Navigation/Tabs to show a child view per tab and use the Tabs for navigation everything works, but if I enter the url of a child view in the browser, the child view is displayed correctly, but the corresponding tab is not selected. This is also the case in the bakery app. Is there already any way to achieve that the tab selects the right tab when entering a child view via url? Tabs.setSelectedTab seems to have no effect in that context.

Thank you very much,

Marco

(Edit: I wouldn’t like to change the first child’s route to “” and remove the route from the MainLayout, which would solve my problem on one side. But on the other side I want the url to be …/child1 when clicking the first tab and /child2 when clicking the second tab. So this is no solution for me.)

My understanding is that BeforeEnterObserver and doing it like this, should work and is the preferred method. It should not end up looping, since MainView route is different from “child”.

@Route(value = "")
public class MainView extends VerticalLayout implements BeforeEnterObserver {

    @Override
    public void beforeEnter(BeforeEnterEvent event) {
         event.rertouteTo("child");
    }

}

Re route will not update URL. Alternatively you could try

@Route(value = "")
public class MainView extends VerticalLayout  {

    @Override
    public void onAttach(AttachEvent event) {
         UI.getCurrent().navigateTo("child");
    }

}

The latter method will update URL.

In this case where you would always want to show child1 as the initial layout you should remove the @Route("") from the MainLayout and just have it as a parentLayout that can’t be navigated to and have the following in child1

@Route(value = "", layout = MainLayout.class)
@RouteAlias(value = "child1", layout = MainLayout.class)

Then child1 will be displayed when navigating to “” or “child1”

Hi Tatu and Mikael,

thanks four your replies! Both solutions work (onAttach and RouteAlias).The reroute solution still ends in an endless loop in my project, but I am using Spring… Maybe the bevahiour is affected from that. The difference between onAttach and RouteAlias is (maybe obvious), that with RouteAlias initially the start url doesn’t change to …/status while onAttach does.

Thanks again,

Marco

The beforeEnter method in the MainLayout will be fired for each navigation event and reroute is no exception.

We have in the plan to see a loop protection for reroute, but right now we only have it for navigate and
it’s up to the developer to not reroute so that you end up in a loop.

Also using the RouteAlias instead of navigate lessens the load on the server as it needs to do less work.