Routing support for TabStrip

1 Answer 1786 Views
TabStrip
Jody
Top achievements
Rank 1
Jody asked on 30 Jun 2021, 02:02 AM

Hi

Am trying to use a TabStrip, integrated with a RouterOutlet to display the tab content.  The module in question has it's own routing, and I hoped to map the router links to tab headers, and thus an outlet for the content.

Without native support for it, I have attempted to place the <router-outlet> in the kendoTabContent element, and manually use the Angular Router on the tabSelect event.   However, on tab change, the router-outlet is destroyed on the old and recreated on the new tab. 

Add in the router navigating and changing the content for router-outlet, and I'm in a lifecycle hook nightmare that isn't feasible the way I have attempted to approach it.   The current component on display in the outlet is destroyed and then instantly recreated as the tab switches, and then router navigation takes over and changes it again.

 

I wanted to ask if there is any planned support for Router integration for TabStrip, like other Layout components have, and/or has anyone had success attempting similar?

Thanks

joe
Top achievements
Rank 1
commented on 20 Jun 2022, 05:55 PM

Hi Preslava,
I am trying to implement a similar solution but am not able to have the tab content displayed within a tab.  The content is being displayed in the original router-outlet element used on the app.component.html and not the router-outlet in the desired html.
I have tried to utilize aux routing but that does not work as the route is not recognized. 

Any suggestions would be greatly appreciated.

1 Answer, 1 is accepted

Sort by
0
Preslava
Telerik team
answered on 02 Jul 2021, 08:15 AM

Hi Jody,

The requested behavior can be achieved by adding the <router-outlet> inside the tab content of the TabStrip. When a tab is selected, the router will navigate to the passed path. This can be done by using the tabSelect event.

public onTabSelect(e) {
    let path = e.title.toLowerCase();
    this.router.navigate(['/' + path]);
}

Please check the following example, which demonstrates this approach:

https://stackblitz.com/edit/angular-s6shx8-beupuk?file=app%2Fapp.component.ts 

I hope this helps.

Regards,
Preslava
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Jody
Top achievements
Rank 1
commented on 13 Jul 2021, 06:41 AM

Hi Preslava,

Thanks for this. This is what I have already been doing.
In addition, we then also need to handle incoming routes, to bind the correct tab to match the router on init. Have this handled, too.

The issue is with the above approach is, the router is quicker than the tab content template being destroyed between tabs. To explain:

1. router.navigate on onTabSelect event
2. router internally does it's thing, and current <router outlet> in current tab receives the output.
3. routed component constructed and begins init, etc.
4. tabswitch catches up. current tab's content template is destroyed.
4a. As such, routed component is destroyed.
5. tabswitch new tab content template created. also has a router outlet (they all do), so router recreates outlet component
6. routed component is constructed and initialised.

So every tab switch, the new destination component on the router is created->destroyed->created.

I dont have a stackblitz for this, but i have two tabs logging ctr/onDestroy, and output on the tabSelect event. It goes like so:

** Started from blank:

tab changed, routing now..
tab 1 ctr
tab 1 destroy
tab 1 ctr
tab changed, routing now..
tab 1 destroy
tab 2 ctr
tab 2 destroy
tab 2 ctr

In tackling the above, I was in the process of converting a large source base to Kendo UI controls from another. In testing the above, i found crashes in other Kendo components, I think it was buttonGroup even, it's ngOnDestroy was null reffing on items that hadn't even been setup yet as part of init - as the instant create/destroy meant things aren't in the normal state yet.

I now can't reproduce this issue today.... (so will try and continue to work with it) but the components being created/destroyed un-necessarily isn't ideal, more complex ones could begin data loads or other processes that are not necessary?

Let me know if you have any suggestions around this. Thanks.
Svet
Telerik team
commented on 16 Jul 2021, 05:08 AM

Hi Jody,

Indeed by default the TabStrip recreates the content for its tabs when a tab is selected. However you could set the keepTabContent option to true as that will make sure for the TabStrip to add the content for its tabs in the DOM once. That way the TabStrip won't re-create the content of its tabs when changing the current tab.

I hope that helps.

Jody
Top achievements
Rank 1
commented on 16 Jul 2021, 06:08 AM

Hi Svet,

If I have flicked between 4 tabs, wouldn't that keep 4 <router-outlet>s in the DOM, each one updating to the latest router output (albeit invisible)?

This would then have 4 instances of a complex component possibly each reacting to observables and the likes.

Unless I misunderstand the keepTabContent operation.

Thanks.
Yanmario
Telerik team
commented on 20 Jul 2021, 10:56 AM | edited

Hi Jody,

Indeed, that would keep four router-outlet's in the DOM. To avoid such a behavior, the router-outlet can be placed outside the TabStrip Component.

 <kendo-tabstrip (tabSelect)="onTabSelect($event)">
      <kendo-tabstrip-tab
        [title]="tab"
        *ngFor="let tab of tabs; let i = index"
        [selected]="i === 0"
      >
        <ng-template kendoTabContent>
          
        </ng-template>
      </kendo-tabstrip-tab>
    </kendo-tabstrip>
    <div class="k-tabstrip">
      <div class="k-content k-state-active">
        <router-outlet></router-outlet>
      </div>
    </div>

StackBlitz example with the small addition of custom CSS:

https://stackblitz.com/edit/angular-s6shx8-ucbmtw?file=app%2Fapp.component.ts

I hope this helps.

Regards,
Yanmario Menev
Progress Telerik
Jody
Top achievements
Rank 1
commented on 20 Jul 2021, 10:57 PM

Thanks Yanmario!

I saw your first update, and thought that won't work because it wont natively look like a tabstrip atall, ie the borders around the content, etc.

Your CSS fix for this is elegant and simple! I like the approach of reusing the k-content styling on the surrounding div outside the tabContent, it looks as if it's natively done.

I'll add this approach into my project today. Thank you.
Jody
Top achievements
Rank 1
commented on 20 Jul 2021, 11:24 PM

It works brilliantly. I have committed this approach!

Thank you very much.
Tags
TabStrip
Asked by
Jody
Top achievements
Rank 1
Answers by
Preslava
Telerik team
Share this question
or