Angular VirtualScroller is an efficient way of rendering lists by displaying a small subset of data in the viewport at any time.
CDK
VirtualScrolling depends on @angular/cdk's ScrollingModule so begin with installing CDK if not already installed.
npm install @angular/cdk --save
Setup
Refer to PrimeNG setup documentation for download and installation steps for your environment.
Import
import {VirtualScrollerModule} from 'primeng/virtualscroller';
Getting Started
VirtualScroller requires a collection of items as its value, height of an item size, height of the scrollable viewport and a ng-template to display where each item can be accessed using the implicit variable.
Throughout the samples, a car interface having vin, brand, year and color properties are used to define an object to be displayed by the VirtualScroller. Cars are loaded by a CarService that connects to a server to fetch the cars with a Promise. Note that this is for demo purposes only, any data source such as an Observable can be used as an alternative as well.
export interface Car {
vin;
year;
brand;
color;
}
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Car } from '../domain/car';
@Injectable()
export class CarService {
constructor(private http: HttpClient) {}
getCarsSmall() {
return this.http.get('/showcase/resources/data/cars-small.json')
.toPromise()
.then(res => <Car[]> res.data)
.then(data => { return data; });
}
}
Here is a sample VirtualScroller that displays a list of cars loaded from a remote datasource.
export class VirtualScrollerDemo implements OnInit {
cars: Car[];
constructor(private carService: CarService) { }
ngOnInit() {
this.carService.getCarsLarge().then(cars => this.cars = cars);
}
}
<p-virtualScroller [value]="cars" scrollHeight="500px" [itemSize]="150">
<ng-template pTemplate="item" let-car>
Car content
</ng-template>
</p-virtualScroller>
Sections
Header and Footer are the two sections that are capable of displaying custom content.
<p-virtualScroller [value]="cars" scrollHeight="500px" [itemSize]="150">
<ng-template pTemplate="header">Header Content</ng-template>
<ng-template pTemplate="item" let-car>
Car content
</ng-template>
<ng-template pTemplate="footer">Footer Content</ng-template>
</p-virtualScroller>
Lazy Loading
Lazy mode is handy to deal with large datasets where instead of loading the entire data, small chunks of data are loaded on demand by invoking onLazyLoad callback everytime scrolling requires a new chunk. To implement lazy loading, enable lazy attribute, initialize your data as a placeholder with a length and finally implement a method callback using onLazyLoad that actually loads a chunk from a datasource. onLazyLoad gets an event object that contains information about the chunk of data to load such as the index and number of items to load. Notice that a new template called loadingItem is also required to display as a placeholder while the new items are being loaded.
<p-virtualScroller [value]="virtualCars" scrollHeight="500px" [itemSize]="150" [rows]="100"
[lazy]="true" (onLazyLoad)="loadCarsLazy($event)">
<ng-template let-car pTemplate="item">
Car content
</ng-template>
<ng-template let-car pTemplate="loadingItem">
Loading...
</ng-template>
</p-virtualScroller>
export class LazyVirtualScrollerDemo implements OnInit {
virtualCars: Car[];
ngOnInit() {
this.cars = Array.from({length: 10000}).map(() => this.carService.generateCar());
this.virtualCars = Array.from({length: 10000});
}
loadCarsLazy(event: LazyLoadEvent) {
//simulate remote connection with a timeout
setTimeout(() => {
//load data of required page
let loadedCars = this.cars.slice(event.first, (event.first + event.rows));
//populate page of virtual cars
Array.prototype.splice.apply(this.virtualCars, [...[event.first, event.rows], ...loadedCars]);
//trigger change detection
this.virtualCars = [...this.virtualCars];
}, 1000);
}
}
Programmatic Scroll
Scrolling to a specific index can be done with the scrollToIndex function.
<button pButton label="Reset" (click)="reset"></button>
<p-virtualScroller #vs [value]="cars" scrollHeight="500px" [itemSize]="150">
<ng-template pTemplate="item" let-car>
Car content
</ng-template>
</p-virtualScroller>
@ViewChild('vs') vs: VirtualScroller;
reset() {
this.vs.scrollToIndex(0, 'smooth');
}
Theming
VirtualScroller supports various themes featuring Material, Bootstrap, Fluent as well as your own custom themes via the Designer tool.
Resources
Visit the PrimeNG VirtualScroller showcase for demos and documentation.