3

My AppComponent contains a sidenav and a router-outlet. Each menu item allows me to navigate to a different feature. Each feature module has four main components:

  • component 1: list => url /feature/list
  • component 2: details => url /feature/details/123
  • component 3: edit => url /feature/edit/123
  • component 4: add => url /feature/add

When I click a feature from the sidenav I'm presented with the features' list-component by default.

On each features' list-component I'm using navigation buttons to navigate to the corresponding details, edit and add components via URL like this: this.router.navigateByUrl('/feature/details/123').

One of my features has a mat-tab-group in its 'details component'. When I navigate to this component (e.g. /feature/details/123) I would also like to be able to click on some tab and see a list-component. But to be clear, I want this component visible within the tab, not in the primary outlet. This list should show a table with some data from id:123. Also this embeded list-component should have different buttons to allow me to navigate to its corresponding details, edit and add components.

I've tried to implement auxiliary routes, and named router-outlets, but I must be doing something wrong because I just can't get this to work. I may not understand the innerworkings properly.

Could someone please explain how I should tackle this? If it is even possible at all?

bluebit
  • 83
  • 1
  • 8
  • Do you want to know how you can add id into the url? https://stackoverflow.com/a/47382088/6108211 – Dmitry Grinko Apr 19 '19 at 13:48
  • @DmitryGrinko Thanks, but that I know. I'm looking for a solution how to have a mat-tab which is part of a child component and navigate between different other child components within that tab. The problem is that if I try it updates the content of the primary outlet. – bluebit Apr 23 '19 at 07:17

1 Answers1

2

You could map a DetailsComponent to the /feature/details route and use the :id route as a child of the details route. In the DetailsComponent you would use the material tabs with routing

in routing module

const routes: Routes = [
  {
    path: 'feature',
    children: [
      {
        path: 'list',
        component: ListComponent
      },
      {
        path: 'details',
        component: DetailsComponent,
        children: [
          {
            path: ':id',
            component: TabIdComponent,
            data:
            {
              title: 'Detail',
            }
          },
          {
            path: 'list',
            component: ListComponent,
            data:
            {
              title: 'List',
            }
          },
          ...
          {
            path: '',
            redirectTo: 'list',
            pathMatch: 'full'
          },
        ]
      },
      ...
    ]
  }

];

in details.component.html

<nav mat-tab-nav-bar>
   <a mat-tab-link
            *ngFor="let tab of tabs"
            [routerLink]="tab.link"
            routerLinkActive
            #rla="routerLinkActive"
            [active]="rla.isActive"
          >
            {{ tab.label }}
   </a>
</nav>
<router-outlet></router-outlet>`

To get the list of tabs from the router config you list it from the ActivatedRoute in the details.component.ts

public tabs: Tab[];

constructor(activatedRoute: ActivatedRoute) {

    activatedRoute.paramMap.subscribe(value => {
      this.tabs = new List(activatedRoute.snapshot.routeConfig.children)
          .Where(r => r.path !== '')
          .Select(r => new Tab(r.path, r.data.title)).ToArray();
    });
  }


...

export class Tab {
    link: string;
    label: string;

    constructor(link: string, label: string) {
        this.label = label;
        this.link = link;
    }
}


If you don't want the ListComponent to ever load in the primary outlet (not even when navigating to /feature/list) you can redirect it to /feature/details/list instead it of defining a component for that route using

{
  path: 'list',
  redirectTo: 'details/list',
  pathMatch: 'full'
}
Sven
  • 97
  • 8