Sachin
Sachin

Reputation: 146

Angular 2 Lazy load Tab content

I have a set of tabs and I want a few tabs to load 'eagerly' and few to load 'lazyily'. For example if I have 2 tabs, Tab1's content should be loaded eagerly and Tab2's contents should load lazyily.

I followed this nice example

<tab tabTitle="Tab 2" lazyload="true">Something like this</tab>

How do I Lazyload the tab content on clicking the tab instead of hiding the loaded content?

Upvotes: 3

Views: 4500

Answers (2)

davaus
davaus

Reputation: 1155

I used Chandermani's suggestion and set up my tabs with select function that set multiple booleans. I am using ngx-bootstrap for the tabs. I then used *ngIf to turn on (and load) the tab contents:

 import { TabsModule } from 'ngx-bootstrap';

In the component....

 tab2Loaded: boolean = false;
 getTab2() { 
    this.tab2Loaded= true; 
 }

in the template...

<tab heading="tab2" (select)="getTab2()">
    <div *ngIf="tab2Loaded" class="container-fluid">
        <div class="row">
               ....etc
        </div> 
    </div> 
</tab>

Seems to work well in Angular 4, although , of course you will need to figure out when you want to load the data. If you want to lazy load it as well, make a component that you pass an id to, which gets its own data.

Upvotes: 1

Thierry Templier
Thierry Templier

Reputation: 202138

I don't really know what you want to implement and what "lazy load" means for you... Do you want to load data asynchronously before displaying the tab? As @TGH stated, routing is a great feature you should consider, especially its @CanActivate decorator:

You could consider to use a load attribute that corresponds to an Observable. The latter would wait for the observable to receive events asynchronously to be displayed.

Here is the new content of your app component:

@Component({
  selector: 'my-app',
  template: `
    <tabs>
      <tab [tabTitle]="'Tab 1'" [load]="tabLoader">Tab 1 Content</tab>
      <tab tabTitle="Tab 2">Tab 2 Content</tab>
    </tabs>
  `,
  directives: [Tabs, Tab]
})
export class App {
  constructor() {
    this.name = 'Angular2';
    this.tabLoader = Observable.create((observer) => {
      setTimeout(() => {
        observer.next();
      }, 1000);
    });
  }
}

And the update within the Tabs component:

@Component({
  (...)
})
export class Tabs implements AfterContentInit {
  (...)

  displayTab(tab) {
    // deactivate all tabs
    this.tabs.toArray().forEach(tab => tab.active = false);

    // activate the tab the user has clicked on.
    tab.active = true;
  }

  selectTab(tab: Tab) {
    if (tab.load) {
      tab.load.subscribe(() => {
        this.displayTab(tab);
      });
    } else {
      this.displayTab(tab);
    }
  }
}

Here is the corresponding plunkr: https://plnkr.co/edit/d54CzKLrJirjkA6TDBC0?p=preview.

Hope it helps you, Thierry

Upvotes: 2

Related Questions