Angular Material Tabs - Load/Unload components only when active tab is selected

Viewed 10967

Given the following code of MainComponent.html:

<mat-tab-group #tabGroup (selectedTabChange)="onTabClick($event)">
  <mat-tab label="Users">
    <!-- Active Tab. This tab is shown first -->
    <app-users></app-users>
  </mat-tab>
  <mat-tab label="Managers">
    <app-managers></app-managers>
  </mat-tab>
</mat-tab-group>

There are two components that are both loaded and ran when this view is called. i.e. the ngOnInit for the ManagersComponent (the inactive tab) is called.

import { Component, OnInit, OnDestroy } from '@angular/core';

@Component({
    selector: 'app-managers',
    templateUrl: './managers.component.html',
    styleUrls: ['./managers.component.scss']
})
export class ManagersComponent implements OnInit, OnDestroy {

    constructor() { }

    ngOnInit() {
      //This is called when the MainComponent is loaded. 
    }

    ngOnDestroy() {

    }
}

Is there a way to load and destroy components so that only the active tab is loaded, and the inactive tabs don't load until they are clicked, and destroyed when left?

i.e. in the code snippet above the ngOnInit won't be loaded for ManagersComponent until the active tab is selected and when left the ngOnDestroy will be called

3 Answers

you can use <ng-template> with the matTabContent attribute in the <mat-tab>

<mat-tab-group #tabGroup (selectedTabChange)="onTabClick($event)">
  <mat-tab label="Users">
    <ng-template matTabContent>
      <app-users></app-users>
    </ng-template>
  </mat-tab>
  <mat-tab label="Managers">
    <ng-template matTabContent>
      <app-managers></app-managers>
    </ng-template>
  </mat-tab>
</mat-tab-group>

see documentation

You can use the *ngIf directive so that the components only gets loaded when the active tab is selected and then destroyed when it becomes inactive. An example would be something like:

<mat-tab-group #tabGroup (selectedTabChange)="onTabClick($event)">
  <mat-tab label="Users">
    <!-- Active Tab. This tab is shown first -->
    <app-users *ngIf="!managerActive"></app-users>
  </mat-tab>
  <mat-tab label="Managers">
    <app-managers *ngIf="managerActive"></app-managers>
  </mat-tab>
</mat-tab-group>

From the Angular Material mat-tab documentation it looks like there is an isActive property you could use as the flag which would probably be the ideal way.

use

<mat-tab-group #tabGroup (selectedTabChange)="onTabClick($event)">
  <mat-tab label="Users">
    <ng-template matTabContent>
      <app-users *ngIf="!managerActive"></app-users>
    </ng-template>
  </mat-tab>
  <mat-tab label="Managers">
    <ng-template matTabContent>
       <app-managers *ngIf="managerActive"></app-managers>
    </ng-template>
  </mat-tab>
</mat-tab-group>

Due to poor documentation of Angular Material, it was hard to find. But ng-template enables lazyloading for tabs. <ng-template matTabContent></ng-template>

Related