import { DoCheck, EmbeddedViewRef, ErrorHandler, NgZone, OnDestroy, OnInit, TemplateRef, TrackByFunction, ViewContainerRef } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { RxVirtualForViewContext } from './list-view-context'; import { RxVirtualScrollStrategy, RxVirtualViewRepeater } from './model'; import { RxVirtualScrollDefaultOptions } from './virtual-scroll.config'; import * as i0 from "@angular/core"; /** * @Directive RxVirtualFor * * @description * * The `*rxVirtualFor` structural directive provides a convenient and performant * way for rendering huge lists of items. It brings all the benefits `rxFor` does, * and implements virtual rendering. * * Instead of rendering every item provided, rxVirtualFor only renders what is * currently visible to the user, thus providing excellent runtime performance * for huge sets of data. * * The technique to render items is comparable to the on used by twitter and * explained in very much detail by @DasSurma in his blog post about the [complexities * of infinite scrollers](https://developer.chrome.com/blog/infinite-scroller/). * * "Each recycling of a DOM element would normally relayout the entire runway which * would bring us well below our target of 60 frames per second. * To avoid this, we are taking the burden of layout onto ourselves and use * absolutely positioned elements with transforms." (@DasSurma) * * ## API * The API is a combination of \@rx-angular/template/for & * \@angular/cdk `*cdkVirtualFor`. * * trackBy: `(index: number, item: T) => any` | `keyof T` * * parent: `boolean`; * * renderCallback: `Subject` * * viewCache: `number` * * (Injected) scrollStrategy: `RxVirtualScrollStrategy` * * provides itself as RxVirtualViewRepeater for RxVirtualViewPortComponent to operate * * ## Features * * Push based architecture * * Comprehensive set of context variables * * Opt-out of `NgZone` with `patchZone` * * Notify when rendering of child templates is finished (`renderCallback`) * * Super efficient layouting with css transformations * * Define a viewCache in order to re-use views instead of re-creating them * * Configurable RxVirtualScrollStrategy providing the core logic to calculate the viewRange and position DOM * Nodes * * ### Context Variables * * The following context variables are available for each template: * * - $implicit: `T` // the default variable accessed by `let val` * - item$: `Observable` // the same value as $implicit, but as `Observable` * - index: `number` // current index of the item * - count: `number` // count of all items in the list * - first: `boolean` // true if the item is the first in the list * - last: `boolean` // true if the item is the last in the list * - even: `boolean` // true if the item has on even index (index % 2 === 0) * - odd: `boolean` // the opposite of even * - index$: `Observable` // index as `Observable` * - count$: `Observable` // count as `Observable` * - first$: `Observable` // first as `Observable` * - last$: `Observable` // last as `Observable` * - even$: `Observable` // even as `Observable` * - odd$: `Observable` // odd as `Observable` * - select: `(keys: (keyof T)[], distinctByMap) => Observable>` * // returns a selection function which * // accepts an array of properties to pluck out of every list item. The function returns the selected properties of * // the current list item as distinct `Observable` key-value-pair. See the example below: * * This example showcases the `select` view-context function used for deeply nested lists. * * ```html * *
*
* {{ hero.name }}
* Defeated enemies: *
* * {{ enemy.name }} * *
*
* ``` * * ### Using the context variables * * ```html * *
*
{{ count }}
*
{{ index }}
*
{{ item }}
*
{{ first }}
*
{{ last }}
*
{{ even }}
*
{{ odd }}
*
*
* ``` * * @docsCategory RxVirtualFor * @docsPage RxVirtualFor * @publicApi */ export declare class RxVirtualFor = Array> implements RxVirtualViewRepeater, OnInit, DoCheck, OnDestroy { private readonly templateRef; private readonly ngZone; readonly viewContainer: ViewContainerRef; private readonly errorHandler; private readonly defaults?; /** @internal */ private _differ?; /** @internal */ private staticValue?; /** @internal */ private renderStatic; /** * @description * The iterable input * * @example * * * * * @param potentialObservable */ set rxVirtualForOf(potentialObservable: Observable | U | null | undefined); /** * @internal * A reference to the template that is created for each item in the iterable. * @see [template reference variable](guide/template-reference-variables) * (inspired by @angular/common `ng_for_of.ts`) */ private _template?; set rxVirtualForTemplate(value: TemplateRef>); /** * @description * Controls the amount if views held in cache for later re-use when a user is * scrolling the list. If this is set to 0, `rxVirtualFor` won't cache any view, * thus destroying & re-creating very often on scroll events. */ templateCacheSize: number; /** * @description * A function or key that defines how to track changes for items in the provided * iterable data. * * When items are added, moved, or removed in the iterable, * the directive must re-render the appropriate DOM nodes. * To minimize operations on the DOM, only nodes that have changed * are re-rendered. * * By default, `rxVirtualFor` assumes that the object instance identifies * the node in the iterable (equality check `===`). * When a function or key is supplied, `rxVirtualFor` uses the result to identify the item node. * * @example * \@Component({ * selector: 'app-root', * template: ` * * * * * ` * }) * export class AppComponent { * items$ = itemService.getItems(); * } * * // OR * * \@Component({ * selector: 'app-root', * template: ` * * * * * ` * }) * export class AppComponent { * items$ = itemService.getItems(); * trackItem = (idx, item) => item.id; * } * * @param trackByFnOrKey */ set trackBy(trackByFnOrKey: keyof T | TrackByFunction); /** * @description * A `Subject` which emits whenever `*rxVirtualFor` finished rendering a * set of changes to the view. * This enables developers to perform actions exactly at the timing when the * updates passed are rendered to the DOM. * The `renderCallback` is useful in situations where you rely on specific DOM * properties like the `height` of a table after all items got rendered. * It is also possible to use the renderCallback in order to determine if a * view should be visible or not. This way developers can hide a list as * long as it has not finished rendering. * * The result of the `renderCallback` will contain the currently rendered set * of items in the iterable. * * @example * \@Component({ * selector: 'app-root', * template: ` * * * * * ` * }) * export class AppComponent { * items$: Observable = itemService.getItems(); * trackItem = (idx, item) => item.id; * // this emits whenever rxVirtualFor finished rendering changes * itemsRendered = new Subject(); * } * * @param renderCallback */ set renderCallback(renderCallback: Subject); private readonly scrollStrategy$; /** @internal */ readonly viewsRendered$: Subject>[]>; /** @internal */ readonly renderingStart$: Subject>; /** @internal */ private get template(); /** @internal */ private observables$; /** @internal */ private _renderCallback?; /** @internal */ readonly values$: Observable; /** @internal */ private _destroy$; private liveCollection?; /** @internal */ _trackBy: TrackByFunction | null; /** @internal */ static ngTemplateContextGuard = Array>(dir: RxVirtualFor, ctx: any): ctx is RxVirtualForViewContext; constructor(templateRef: TemplateRef>, ngZone: NgZone, viewContainer: ViewContainerRef, errorHandler: ErrorHandler, defaults?: RxVirtualScrollDefaultOptions); /** @internal */ ngOnInit(): void; /** @internal */ ngDoCheck(): void; /** @internal */ ngOnDestroy(): void; setScrollStrategy(scrollStrategy: RxVirtualScrollStrategy): void; private render; private getAllViewsFromViewContainer; static ɵfac: i0.ɵɵFactoryDeclaration, [null, null, null, null, { optional: true; }]>; static ɵdir: i0.ɵɵDirectiveDeclaration, "[rxVirtualFor][rxVirtualForOf]", never, { "rxVirtualForOf": "rxVirtualForOf"; "rxVirtualForTemplate": "rxVirtualForTemplate"; "templateCacheSize": "rxVirtualForTemplateCacheSize"; "trackBy": "rxVirtualForTrackBy"; "renderCallback": "rxVirtualForRenderCallback"; }, {}, never>; } export declare class RxVirtualForModule { static ɵfac: i0.ɵɵFactoryDeclaration; static ɵmod: i0.ɵɵNgModuleDeclaration; static ɵinj: i0.ɵɵInjectorDeclaration; }