I am trying to create a tabbar that works similarly to the browser tabs. Each tab loads a module.
I am trying with mat-tab-nav-bar
. Opening a new tab and setting it active as well as switching back and forth between tabs works fine. Closing a tab works and the tab is deleted from the array. Unfortunately, I cannot make the previously opened tab or the tab next to the closed tab active again and load the module. I put the last loaded and active page into the sessionStorage
and load this page after a reload in the ngOnInit()
function.
Angular and TypeScript are still new to me and I haven't gained much experience yet.
I have taken this example as a template. I also tried with this example, but I could not load any modules and with mat-tab-nab-bar it worked fine. https://stackblitz.com/edit/angular-zzehu6?file=src%2Fapp%2Ftab-group-dynamic-example.html
If a tab is to be deleted, the onRemoveTab()
event is triggered. There I loop over the tabs and as soon as the tab to be deleted is found, I remove it from the Tabs array and set the previous tab in the FormControler
as Active (or try to set it Active). I also save this tab in the sessionStorage
.
The result is that only the deleted tab is removed, but the previous tab is not set active and the module is not reloaded.
How can I make this happen? Does anyone have an idea?
Here is my code. Please let me know if you need more information.
tabbar.component.html
<div *ngIf="currentTab">
<nav mat-tab-nav-bar>
<a
mat-tab-link
*ngFor="let tab of tabs; let index = index"
[routerLink]="tab.link"
routerLinkActive="false"
#rla="routerLinkActive"
[active]="rla.isActive"
(click)="onSelect(tab, index)"
disableRipple
>
{{tab.name}}
<button
mat-icon-button
(click)="onRemoveTab(tab.id, index)"
[disabled]="tabs.length === 1"
>
<mat-icon style="transform: scale(0.8);">close</mat-icon>
</button>
</a>
</nav>
</div>
<div class="content">
<ng-content></ng-content>
</div>
tabbar.component.ts
import { Component, Input, OnChanges, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { SidenavRouteInterface } from './data';
@Component({
selector: 'tabbar',
templateUrl: './tabbar.component.html',
})
export class TabbarComponent implements OnChanges, OnInit {
selected = new FormControl(0);
tabs: SidenavRouteInterface[] = [];
sessionKey = 'currentTab';
previousTab: SidenavRouteInterface | undefined;
onSelect(router: SidenavRouteInterface, index: number) {
sessionStorage.setItem(this.sessionKey, JSON.stringify(router));
this.selected.setValue(router.id);
}
onRemoveTab(tabId: number, index: number) {
this.tabs.forEach((tab) => {
if (tab.id === tabId) {
this.tabs.splice(index, 1);
this.selected.setValue(this.previousTab?.id);
sessionStorage.setItem(this.sessionKey, JSON.stringify(this.previousTab));
} else {
this.previousTab = tab;
}
});
return false;
}
}
sidenav-route.model.ts
export interface SidenavRouteInterface {
id: number;
name: string;
link: string;
icon?: string;
}
An example of how a tab in the array can look.
tabs: SidenavRouteInterface[] = [
{ id: 6, name: 'Document', link: 'document' },
{ id: 7, name: 'Reference', link: 'reference' },
];
Result:
this.router.navigate([this.previousTab.link])
does the trick.
onRemoveTab(tabId: number, index: number) {
this.tabs.forEach((tab) => {
if (tab.id === tabId) {
this.tabs.splice(index, 1);
this.selected.setValue(this.previousTab?.id);
this.router.navigate([this.previousTab.link]);
sessionStorage.setItem(this.sessionKey, JSON.stringify(this.previousTab));
} else {
this.previousTab = tab;
}
});
return false;
}