Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b00b41d

Browse files
committed
feat(template): add DataSource support for rx-virtual-for directive
1 parent 3f91916 commit b00b41d

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

libs/template/experimental/virtual-scrolling/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export {
2+
CollectionViewer,
3+
DataSource,
24
ListRange,
35
RxVirtualForViewContext,
46
RxVirtualScrollElement,

libs/template/experimental/virtual-scrolling/src/lib/model.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ export interface ListRange {
3434
end: number;
3535
}
3636

37+
export abstract class DataSource<T> {
38+
abstract connect(
39+
collectionViewer: CollectionViewer,
40+
): Observable<NgIterable<T>>;
41+
abstract disconnect(collectionViewer: CollectionViewer): void;
42+
}
43+
44+
export interface CollectionViewer {
45+
viewChange: Observable<ListRange>;
46+
}
47+
3748
/**
3849
* @Directive RxVirtualScrollStrategy
3950
*

libs/template/experimental/virtual-scrolling/src/lib/virtual-for.directive.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { Promise } from '@rx-angular/cdk/zone-less/browser';
3434
import {
3535
combineLatest,
3636
concat,
37+
ConnectableObservable,
3738
isObservable,
3839
MonoTypeOperatorFunction,
3940
NEVER,
@@ -55,6 +56,8 @@ import {
5556
tap,
5657
} from 'rxjs/operators';
5758
import {
59+
CollectionViewer,
60+
DataSource,
5861
ListRange,
5962
RxVirtualForViewContext,
6063
RxVirtualScrollStrategy,
@@ -241,6 +244,7 @@ export class RxVirtualFor<T, U extends NgIterable<T> = NgIterable<T>>
241244
potentialSignalOrObservable:
242245
| Observable<(U & NgIterable<T>) | undefined | null>
243246
| Signal<(U & NgIterable<T>) | undefined | null>
247+
| DataSource<T>
244248
| (U & NgIterable<T>)
245249
| null
246250
| undefined,
@@ -251,6 +255,21 @@ export class RxVirtualFor<T, U extends NgIterable<T> = NgIterable<T>>
251255
this.observables$.next(
252256
toObservable(potentialSignalOrObservable, { injector: this.injector }),
253257
);
258+
} else if (this.isDataSource(potentialSignalOrObservable)) {
259+
this.staticValue = undefined;
260+
this.renderStatic = false;
261+
262+
const collectionViewer: CollectionViewer = {
263+
viewChange: this.scrollStrategy.renderedRange$,
264+
};
265+
266+
this.observables$.next(
267+
potentialSignalOrObservable.connect(collectionViewer),
268+
);
269+
270+
this._destroy$.pipe(take(1)).subscribe(() => {
271+
potentialSignalOrObservable.disconnect(collectionViewer);
272+
});
254273
} else if (!isObservable(potentialSignalOrObservable)) {
255274
this.staticValue = potentialSignalOrObservable;
256275
this.renderStatic = true;
@@ -261,6 +280,24 @@ export class RxVirtualFor<T, U extends NgIterable<T> = NgIterable<T>>
261280
}
262281
}
263282

283+
/** @internal */
284+
private isDataSource(
285+
value:
286+
| (U & NgIterable<T>)
287+
| Observable<U & NgIterable<T>>
288+
| DataSource<T>
289+
| null
290+
| undefined,
291+
): value is DataSource<T> {
292+
return (
293+
value !== null &&
294+
value !== undefined &&
295+
'connect' in value &&
296+
typeof value.connect === 'function' &&
297+
!(value instanceof ConnectableObservable)
298+
);
299+
}
300+
264301
/**
265302
* @internal
266303
* A reference to the template that is created for each item in the iterable.

0 commit comments

Comments
 (0)