0
votes

I have an odd problem and do not seem to find the issue. I have a child router with two viewports and would like to access the router in one of the components (menu) loaded through the viewport. When I define the same routes with the viewports in the app.ts, the menu shows the route entries, but with the routes defined in the child router the router variable is undefined. I tried with a viewmodel for the menu and also with binding the router explicitly to the router-view tag, but no luck.

Would be great if someone could shed some light on this.

The reason for this is that I would like to create a different page layout with these viewports compared to an admin page. However I'm not sure if this separation is actually a good aproach. Maybe I could simply set the side viewport null for the admin page. But this would require some CSS rewriting I believe.

app.ts

config.map([
      {
        route: ['', 'child'],
        name: 'child',
        moduleId: 'child/child',
      },
      {
        route: 'admin',
        name: 'admin',
        moduleId: 'admin/admin,
      },
    ]);

this.router = router;

child view

<template> 
  [...]
  <router-view name="side"></router-view>

  <router-view name="main"></router-view>
</template>

child vm

export class Child{
  private router: Router

  private configureRouter(config: RouterConfiguration, router: Router){
    config.map([
      {
        route: 'myOrders',
        name: 'myOrders',
        nav: true,
        viewPorts: {
          main: { moduleId: 'components/some-vm/some-vm' },
          side: { moduleId: 'components/menu/menu.html' }
        }
      },
      {
        route: ['', 'allorders'],
        name: 'allorders',
        nav: true,
        viewPorts: {
          main: { moduleId: 'components/orders-table/orders-table' },
          side: { moduleId: 'components/menu/menu.html' }
        }
      }
    ]);

    this.router = router;
  }
}

menu view

<template> 
  [...]
  ${router}  <!-- router is never accessible -->
  <ul class="nav">
    <li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">
      <a href.bind="row.href">${row.title}</a>
    </li>
  </ul>
</template>
1
sounds like not an optimal approach. consider using compose.Matthew James Davis

1 Answers

1
votes

The binding context inside a router-view is not merged with the parent binding context. You might be able to do $parent.router (not tested this), but it's better to simply inject Router in the constructor of your menu view.

To clarify: every child router will get its own child container. Components which are loaded by that child router will have their dependencies resolved from that child container. Things like Router and Element are automatically registered to that child container, meaning you'll always get the "innermost" or "closest" instance relative to the component you're requesting it from.

So if you inject Router in your App, you'll get the root (AppRouter) and if you inject it in your menu view, you'll get the child router you need.