Skip to main content

RxVirtualFor

*rxVirtualFor is a structural directive that renders only the items currently visible in a RxVirtualScrollViewport, instead of rendering the whole iterable. It implements RxVirtualViewRepeater and schedules the change detection of each child template through concurrent render strategies.

Why this matters: see Concurrent scheduling & the frame budget and How RxAngular virtual scrolling works.

Import

import { RxVirtualFor } from '@rx-angular/template/virtual-scrolling';

Selector

  • [rxVirtualFor][rxVirtualForOf]

RxVirtualFor is standalone: true and provides itself as RxVirtualViewRepeater. It must be placed inside a <rx-virtual-scroll-viewport> that has a scroll strategy applied.

Type parameters

class RxVirtualFor<T, U extends NgIterable<T> = NgIterable<T>>

Inputs

The microsyntax input rxVirtualForOf accepts an Observable, a Signal, or a static (unwrapped) value.

InputMicrosyntax aliasTypeDefaultDescription
rxVirtualForOfof / inObservable<U> \| Signal<U> \| U \| null \| undefinedThe iterable to render. A Signal or plain array is treated as a static value.
trackBytrackBykeyof T \| ((index: number, item: T) => unknown)Identity for items. Accepts a property name shorthand (trackBy: 'id') or a TrackByFunction.
strategystrategyRxStrategyNames<string> \| Observable<RxStrategyNames<string>>'normal'The render strategy used to schedule change detection. See tuning rendering with strategies.
renderCallbackrenderCallbackSubject<U>Emits the currently rendered set of items whenever the directive finishes rendering a change set.
templateCacheSizetemplateCacheSizenumber20Number of views held in cache for re-use while scrolling. 0 disables caching (views are destroyed and re-created on scroll).
parentparentbooleanfalseWhen true, runs change detection on the host component after rendering so @ContentChild/@ViewChild queries stay in sync. Deprecated: no longer required with signal-based view/content queries. See handling view and content queries.
patchZonepatchZonebooleantrue (from RxRenderStrategiesConfig)When false, the directive creates its EmbeddedViews outside NgZone.
Deprecated input

parent (microsyntax rxVirtualForParent) is @deprecated in the source: "this flag will be dropped soon, as it is no longer required when using signal based view & content queries." Its default is false.

Context variables

Each rendered template exposes the following context variables.

Static context variables (mirrored from ngFor)

VariableTypeDescription
$implicitTThe item, accessed by let item.
indexnumberCurrent index of the item.
countnumberCount of all items in the list.
firstbooleantrue if the item is first.
lastbooleantrue if the item is last.
evenbooleantrue if index % 2 === 0.
oddbooleanThe opposite of even.

Reactive context variables

VariableTypeDescription
item$Observable<T>The same value as $implicit, as an Observable.
index$Observable<number>index as an Observable.
count$Observable<number>count as an Observable.
first$Observable<boolean>first as an Observable.
last$Observable<boolean>last as an Observable.
even$Observable<boolean>even as an Observable.
odd$Observable<boolean>odd as an Observable.
select(keys: (keyof T)[]) => Observable<any>Returns a selection function that plucks the given properties from the current item and emits them as a distinct Observable key-value pair.

Configuration

Provide RX_VIRTUAL_SCROLL_DEFAULT_OPTIONS to pre-configure package-wide defaults for the virtual-scrolling directives.

import { RX_VIRTUAL_SCROLL_DEFAULT_OPTIONS } from '@rx-angular/template/virtual-scrolling';

bootstrapApplication(AppComponent, {
providers: [
{
provide: RX_VIRTUAL_SCROLL_DEFAULT_OPTIONS,
useValue: {
// of type `RxVirtualScrollDefaultOptions`
runwayItems: 50,
templateCacheSize: 0, // turn off cache by default
},
},
],
});

RxVirtualScrollDefaultOptions

interface RxVirtualScrollDefaultOptions {
/** how many templates can be cached and re-used on rendering — defaults to 20 */
templateCacheSize?: number;
/** how many views are rendered upfront in scroll direction — defaults to 10 */
runwayItems?: number;
/** how many views are rendered upfront in the opposite scroll direction — defaults to 2 */
runwayItemsOpposite?: number;
/** default item size used by the scroll strategies; also the tombstone size for the autosized strategy */
itemSize?: number;
}

Default values

When no RX_VIRTUAL_SCROLL_DEFAULT_OPTIONS are provided, the directives fall back to these built-in defaults: templateCacheSize is 20, itemSize is 50, runwayItems is 10, and runwayItemsOpposite is 2. These values are internal to the package and are not exported as importable symbols; override them through RX_VIRTUAL_SCROLL_DEFAULT_OPTIONS or the corresponding directive inputs.

Minimal example

import { Component, Signal } from '@angular/core';
import { FixedSizeVirtualScrollStrategy, RxVirtualScrollViewportComponent, RxVirtualFor } from '@rx-angular/template/virtual-scrolling';

@Component({
imports: [RxVirtualFor, RxVirtualScrollViewportComponent, FixedSizeVirtualScrollStrategy],
template: `
<rx-virtual-scroll-viewport [itemSize]="50">
<div *rxVirtualFor="let movie of movies()">
<strong>{{ movie.name }}</strong>
</div>
</rx-virtual-scroll-viewport>
`,
})
export class ListComponent {
movies: Signal<Movie[]> = inject(MovieService).fetchMovies();
}

*rxVirtualFor ships the non-star structural syntax; the * is the standard Angular structural-directive shorthand and stays valid.

See also