Home > Software design >  Calling OnInit for current and previous tab during tab change
Calling OnInit for current and previous tab during tab change

Time:11-01

In a angular i added a tab control, but list of available tabs i will get from backend. so i added a code to display template base on some key . but every time when i switch a tab, I can see OnInit event for a new tab and for a current. I dont need to load a current tab infor again, so, perfectly, it should call onDestroy for a current tab and OnInit for a new.

<mat-tab-group disableRipple (selectedTabChange)="tabChange($event)">
<ng-container *ngFor="let info of tabs">
  <mat-tab [label]="info.title">
    <ng-template matTabContent>
      <ng-container *ngIf="selectedTab == 'step1'">
        <app-step1></app-step1>
      </ng-container>
      <ng-container *ngIf="selectedTab == 'step2'">
        <app-step2></app-step2>
      </ng-container>
      <ng-container *ngIf="selectedTab == 'step3'">
        <app-step3></app-step3>
      </ng-container>
    </ng-template>
  </mat-tab>
</ng-container>
</mat-tab-group> 

i tried to do instead of ngIf add a [hidden] attribute and tried to do a switch, but still not correct behaviour for me

added a code with an issue. stackblitz

CodePudding user response:

If you want to use ngIf, you just need to check on the tab tabKey in your ngIf and not the selected tab. Simple logic if the tab tabKey is step1 then render the step1 component and so on. Mat tab takes care of rendering the active tab content.

Even if you use the hidden solution or display none, mat tab rerender the active component and destroy the previous selected ones.

<mat-tab-group disableRipple (selectedTabChange)="tabChange($event)">
  <mat-tab *ngFor="let info of tabs" [label]="info.title">
    <ng-template matTabContent>
      <app-step1 *ngIf="info.tabKey == 'step1'"></app-step1>
      <app-step2 *ngIf="info.tabKey == 'step2'"></app-step2>
      <app-step3 *ngIf="info.tabKey == 'step3'"></app-step3>
    </ng-template>
  </mat-tab>
</mat-tab-group>

Here is my working stackblitz example

CodePudding user response:

I have encountered a similar issue and our solution was to apply display: none on the tabs instead of *ngIf to prevent re-rendering.

.html

<mat-tab-group disableRipple (selectedTabChange)="tabChange($event)">
<ng-container *ngFor="let info of tabs">
  <mat-tab [label]="info.title">
    <ng-template matTabContent>
      <ng-container [class.hide-tab]="selectedTab !== 'step1'">
        <app-step1></app-step1>
      </ng-container>
      <ng-container [class.hide-tab]="selectedTab !== 'step2'">
        <app-step2></app-step2>
      </ng-container>
      <ng-container [class.hide-tab]="selectedTab !== 'step3'">
        <app-step3></app-step3>
      </ng-container>
    </ng-template>
  </mat-tab>
</ng-container>
</mat-tab-group> 

.css

.hide-tab {
  display: none;
}

Note: This means that all of your tabs will load on page load, but only the content one of them will be shown at a time. If you don't want this to happen you may need to apply some more conditional logic and a combination of *ngIf and display: none

  • Related