Skip to main content

Implementing Virtual and Infinite Scroll

1. Creating Virtual Scroll

Property Description Default Notes
ionVirtualScroll Directive to enable virtual scrolling on a list undefined Must be applied to ion-list or ion-content
items Array of items to render in the virtual scroll undefined Required property for virtual scroll
approxItemHeight Approximate height of each item in pixels 40px Improves performance by estimating item heights
headerFn Function to generate header for groups undefined Used with grouped data
footerFn Function to generate footer for groups undefined Used with grouped data

Example: Basic Virtual Scroll Implementation

import { Component } from '@angular/core';

@Component({
  selector: 'app-virtual-scroll',
  template: &#x27;<ion-content>
  <ion-list>
    <ion-item *ionVirtualScroll="let item of items">
      <div>{{ item.name }}</div>
    </ion-item>
  </ion-list>
</ion-content>&#x27;
})
export class VirtualScrollPage {
  items = Array.from({ length: 1000 }, (_, i) => ({
    name: `Item ${i + 1}`
  }));
}

Example: Virtual Scroll with Approximate Item Height

import { Component } from '@angular/core';

@Component({
  selector: 'app-virtual-scroll',
  template: &#x27;<ion-content>
  <ion-list>
    <ion-item *ionVirtualScroll="let item of items" [approxItemHeight]="60">
      <div>{{ item.name }} - {{ item.description }}</div>
    </ion-item>
  </ion-list>
</ion-content>&#x27;
})
export class VirtualScrollPage {
  items = Array.from({ length: 1000 }, (_, i) => ({
    name: `Item ${i + 1}`,
    description: `Description for item ${i + 1}`
  }));
}
Note: Virtual scroll is particularly useful for large lists where performance is a concern. It only renders items that are currently visible in the viewport, significantly reducing DOM overhead.

2. Configuring Virtual Scroll

Property Values Description
ionVirtualScroll boolean Enables virtual scrolling on the component. Default is false.
approxItemHeight number Approximate height of each item in pixels. Used for calculating the number of items to render.
headerFn (index: number) => string Function to generate header content for groups of items.
footerFn (index: number) => string Function to generate footer content for groups of items.

Example: Basic Virtual Scroll Configuration

<ion-list>
  <ionVirtualScroll approxItemHeight="100">
    <ion-item *virtualItem="let item">
      <ion-label>{{ item.name }}</ion-label>
    </ion-item>
  </ionVirtualScroll>
</ion-list>
Note: The approxItemHeight property is crucial for performance. If set incorrectly, it can lead to rendering issues or excessive memory usage.

3. Implementing Infinite Scroll

Example: Basic Infinite Scroll Implementation

import { Component } from '@angular/core';

@Component({
  selector: 'app-infinite-scroll',
  template: &#x27;<ion-content>
  <ion-list>
    <ion-item *ngFor="let item of items">
      {{ item }}
    </ion-item>
  </ion-list>
  <ion-infinite-scroll (ionInfinite)="loadData($event)">
    <ion-infinite-scroll-content></ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>&#x27;
})
export class InfiniteScrollComponent {
  items = [];

  loadData(event) {
    for (let i = 0; i < 50; i++) {
      this.items.push(`Item ${this.items.length + 1}`);
    }
    event.target.complete();
  }
}
Property Values Description
ionInfinite (ionInfinite) Event emitted when the infinite scroll reaches the end
complete() void Method to call when data loading is complete
disabled boolean Disables the infinite scroll if true
Note: The complete() method must be called to signal that new data has been loaded and the scroll is ready for more data.

Example: Infinite Scroll with Loading State

import { Component } from '@angular/core';

@Component({
  selector: 'app-infinite-scroll',
  template: &#x27;<ion-content>
  <ion-list>
    <ion-item *ngFor="let item of items">
      {{ item }}
    </ion-item>
  </ion-list>
  <ion-infinite-scroll (ionInfinite)="loadMore($event)">
    <ion-infinite-scroll-content
      loadingSpinner="dots"
      loadingText="Loading more data...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>&#x27;
})
export class InfiniteScrollComponent {
  items = [];
  loading = false;

  loadMore(event) {
    this.loading = true;
    setTimeout(() => {
      for (let i = 0; i < 20; i++) {
        this.items.push(`Item ${this.items.length + 1}`);
      }
      event.target.complete();
      this.loading = false;
    }, 1000);
  }
}

4. Using Infinite Scroll Content

Property Description Values
ion-infinite-scroll Component to implement infinite scroll <ion-infinite-scroll>
ion-infinite-scroll-content Content to display during infinite scroll <ion-infinite-scroll-content>
position Position of the infinite scroll content 'top', 'bottom'
spinner Spinner to display during loading 'bubbles', 'circles', 'crescent', 'dots', 'lines', 'lines-sharp', 'lines-small', 'lines-small-sharp', 'none'
loadingText Text to display during loading string

Example: Basic Infinite Scroll Content

<ion-infinite-scroll>
  <ion-infinite-scroll-content
    loadingText="Loading more data..."
    spinner="bubbles">
  </ion-infinite-scroll-content>
</ion-infinite-scroll>

Example: Infinite Scroll with Custom Spinner

<ion-infinite-scroll>
  <ion-infinite-scroll-content
    loadingText="Loading more items..."
    spinner="lines">
  </ion-infinite-scroll-content>
</ion-infinite-scroll>
Note: The ion-infinite-scroll-content component is used to define the content that appears during infinite scroll operations. It supports various spinner types and custom loading text.

5. Handling Infinite Event

Property Description Values
ionInfiniteScroll Event emitted when the infinite scroll reaches the end of the content true to enable infinite scroll
ionInfinite Handler function for the infinite scroll event Function that returns a Promise or void

Example: Handling Infinite Scroll Event

import { Component, ViewChild } from '@angular/core';
import { IonInfiniteScroll } from '@ionic/angular';

@Component({
  selector: 'app-infinite-scroll',
  template: '<ion-content>' +
    '<ion-list>' +
    '<ion-item *ngFor="let item of items">{{ item }}</ion-item>' +
    '</ion-list>' +
    '<ion-infinite-scroll (ionInfinite)="loadData($event)">' +
    '<ion-infinite-scroll-content></ion-infinite-scroll-content>' +
    '</ion-infinite-scroll>' +
    '</ion-content>'
})
export class InfiniteScrollPage {
  @ViewChild(IonInfiniteScroll) infiniteScroll: IonInfiniteScroll;

  items = [];

  loadData(event) {
    setTimeout(() => {
      const newItems = Array.from({ length: 10 }, (_, i) =>
        `Item ${this.items.length + i + 1}`
      );
      this.items.push(...newItems);

      event.target.complete();

      if (this.items.length >= 100) {
        event.target.disabled = true;
      }
    }, 500);
  }
}
Note: The event.target.complete() must be called to signal that the loading is done and the scroll can continue.
Warning: If event.target.disabled = true is not set, the infinite scroll will keep firing events even after all items are loaded.

6. Disabling Infinite Scroll

Property Values Description
disabled false | true Disables the infinite scroll functionality when set to true.

Example: Disabling Infinite Scroll

<ion-infinite-scroll [disabled]&#x3D;"isDisabled">
  <ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>

Example: Toggle Infinite Scroll

export class MyComponent {
  isDisabled = false;

  toggleInfiniteScroll() {
    this.isDisabled = !this.isDisabled;
  }
}

7. Completing Infinite Scroll

Example: Marking Infinite Scroll as Complete

component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-infinite-scroll',
  templateUrl: './infinite-scroll.component.html'
})
export class InfiniteScrollComponent implements OnInit {
  items: string[] = [];

  constructor() { }

  ngOnInit() {
    this.loadItems();
  }

  loadItems() {
    // Simulate API call
    setTimeout(() => {
      const newItems = Array.from({ length: 20 }, (_, i) => `Item ${this.items.length + i + 1}`);
      this.items.push(...newItems);
    }, 1000);
  }

  async completeInfiniteScroll(event: any) {
    await this.loadItems();
    event.target.complete(); // Mark scroll as complete
  }
}
Method Description Usage
event.target.complete() Signals that the infinite scroll has finished loading data Call after new items are added to the list
event.target.disabled = true Disables the infinite scroll functionality Use when all data has been loaded
Note: Always call event.target.complete() to prevent duplicate loading of data.
Warning: If complete() is not called, the scroll will continue to trigger load events even when no more data is available.

8. Setting Scroll Threshold

Property Values Description
threshold 100px, 10% Distance from the bottom of the scroll container to trigger infinite scroll

Example: Setting Scroll Threshold

<ion-infinite-scroll threshold="10%">
  <ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
Note: The threshold can be specified as a pixel value or percentage of the scroll container's height.

9. Using Loading Spinner

Property Description Default Notes
loadingSpinner Spinner type to display 'crescent' Options: 'bubbles', 'circles', 'crescent', 'dots', 'lines', 'pause', 'pointer', 'ripple', 'spiral'
loadingSpinnerColor Color of the spinner 'primary' Any valid CSS color or Ionic color name

Example: Configuring Loading Spinner

import { Component } from '@angular/core';

@Component({
  selector: 'app-infinite-scroll',
  template: &#x27;<ion-content>
  <ion-list>
    <ion-item *ngFor="let item of items">
      {{ item }}
    </ion-item>
  </ion-list>
  <ion-infinite-scroll (ionInfinite)="loadData($event)">
    <ion-infinite-scroll-content
      loadingSpinner="dots"
      loadingSpinnerColor="secondary">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>&#x27;
})
export class InfiniteScrollComponent {
  items = [];

  loadData(event) {
    setTimeout(() => {
      for (let i = 0; i < 50; i++) {
        this.items.push(`Item ${this.items.length + 1}`);
      }
      event.target.complete();
    }, 500);
  }
}
Note: The loadingSpinner property can be customized to match the app's theme or provide visual feedback during data loading. The loadingSpinnerColor allows for consistent color integration with the app's design system.

10. Positioning Infinite Scroll

Property Values Description
position "top" | "bottom" Sets the position of the infinite scroll listener. Default is "bottom".
distance "10%" | "50px" Defines how far from the edge of the scroll container the listener should trigger. Default is "10%".

Example: Setting Position to Top

<ion-infinite-scroll position="top">
  <ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
Note: When position is set to "top", the scroll listener will trigger when the user scrolls near the top of the content.

Was this article helpful?