1

For my application, I have a dropdown of 'Statements' which a user can select. When the user selects a specific statement, an API call is made that retrieves ways of how this data has to be displayed, called ViewOptions. The format looks as follows:

[
  {
    "Id": 1,
    "OptionName": "Graph and table"
  },
  {
    "Id": 3,
    "OptionName": "Query results"
  }
]

Now I have a different component that will be rendered when the viewoptions are loaded that should display a tab with information depending on the view options. So in this example, there is a tab where a graph and table of data have to be shown, and another tab where results of a query have to be shown.

In the tab component, I have the following HTML:

<ngb-tabset justify="justified" *ngIf="viewOptions.length">
  <ngb-tab *ngFor="let vo of viewOptions" id="{{vo.Id}}">
    <ng-template ngbTabTitle>{{vo.OptionName}}</ng-template>
    <ng-template ngbTabContent></ng-template>
  </ngb-tab>
</ngb-tabset>

So, for each viewoption, a tab will be rendered with the correct title. Now my confusion lies with how I should deal with the 'ngbTabContent' thing. Herein I want a specific component depending on the viewoption, for example if it's a "Graph and table", I have the component, for "Query results" I have the component, and so on... I am pretty new to Angular2 and I have a feeling I will have to do this with some sort of templating but the fact I have to do this dynamically depending on that 'vo' parameter in an *ngFor messes a bit with my head.

2

2 Answers 2

1

You can resolve it by adding child route. You need to place router-outlet instead of ngTabContent, link your dynamic components as the child route and redirect to a proper one.

Your parent component HTML

<ngb-tabset justify="justified" *ngIf="viewOptions.length">
  <ngb-tab *ngFor="let vo of viewOptions" id="{{vo.Id}}">
    <ng-template ngbTabTitle>{{vo.OptionName}}</ng-template>
  </ngb-tab>
  <router-outlet></router-outlet>
</ngb-tabset>

Your parent component code

onBackendResponse(res) {
   if (res.dynamicComponent === 'first') {
      this.router.navigateByUrl('firstDynamic');
   } else if (res.dynamicComponent === 'second') {
      this.router.navigateByUrl('secondDynamic');
   }
}

Your routing

const appRoutes: Routes = [ 
  {
    path: 'parent', component: ParentComponent, children: [
      { path: 'firstDynamic', component: FirstDynamic },
      { path: 'secondDynamic', component: SecondDynamic }
    ]
  },
];  
Sign up to request clarification or add additional context in comments.

4 Comments

I'm kinda seeing what you're getting at and tried it, but I was already using a router outlet somewhere and was afraid that doing this, my other router outlet would also match this navigation. My suspicions were correct so now it just replaces my whole page (where the router-outlet is) with this route, instead of only the content of the correct tab... Can I circumvent this or will another solution be more appropriate in this case?
Never mind, I missed the part where you had to link up the route to the parent component, derp... I fixed it and it works like this, much obliged. :)
Never mind again... For one, I already found this solution a little icky sicne I didn't want another router-outlet and to mess with my routes just to display some tabs, and secondly, while it seemed to work, whenever I switched tabs, it initially worked, but when I switched back, the content of that tab didn't get shown. I found another solution (which in my opinion is a lot cleaner as well) that actually 'templates' the content of the tabs.
When I was thinking about the answer, my first thought was about dynamically loaded components. The problem with that solution is that you loose the tab state in case of reloading or linking the page.
0

After trying SirWojtek's solution and not really finding it suitable to my needs (see my comments on his answer), I found the following link and the solution provided under the paragraph "Dynamic Components" was exactly what I was looking for: https://medium.com/@DenysVuika/dynamic-content-in-angular-2-3c85023d9c36

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.