8000 feat(template): add DataSource support for rx-virtual-for directive by friendlyAce · Pull Request #1764 · rx-angular/rx-angular · GitHub
[go: up one dir, main page]

Skip to content

feat(template): add DataSource support for rx-virtual-for directive #1764

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fix(template): improve DataSource lifecycle management in RxVirtualFor
- Renamed potentialSignalOrObservable to potentialSignalOrObservableOrDataSource
- Move DataSource disconnect from subscription to ngOnDestroy lifecycle
- Add disconnectDataSource() method for centralized cleanup logic
- Ensure disconnect and cleanup of previous data source on data source input changes to prevent memory leaks
  • Loading branch information
friendlyAce committed May 24, 2025
commit 09270f99f65dc3579a9030d2a2e0b93a09e16ebf
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ export class RxVirtualFor<T, U extends NgIterable<T> = NgIterable<T>>
optional: true,
});

/** @internal */
private connectedDataSource?: DataSource<T>;
/** @internal */
private collectionViewer?: CollectionViewer;

/** @internal */
private _differ?: IterableDiffer<T>;

Expand All @@ -237,46 +242,49 @@ export class RxVirtualFor<T, U extends NgIterable<T> = NgIterable<T>>
* [hero]="hero"></app-hero>
* </rx-virtual-scroll-viewport>
*
* @param potentialSignalOrObservable
* @param potentialSignalOrObservableOrDataSource
*/
@Input()
set rxVirtualForOf(
potentialSignalOrObservable:
potentialSignalOrObservableOrDataSource:
| Observable<(U & NgIterable<T>) | undefined | null>
| Signal<(U & NgIterable<T>) | undefined | null>
| DataSource<T>
| (U & NgIterable<T>)
| null
| undefined,
) {
if (isSignal(potentialSignalOrObservable)) {
if (isSignal(potentialSignalOrObservableOrDataSource)) {
this.staticValue = undefined;
this.renderStatic = false;
this.observables$.next(
toObservable(potentialSignalOrObservable, { injector: this.injector }),
toObservable(potentialSignalOrObservableOrDataSource, {
injector: this.injector,
}),
);
} else if (this.isDataSource(potentialSignalOrObservable)) {
} else if (this.isDataSource(potentialSignalOrObservableOrDataSource)) {
this.disconnectDataSource();

this.staticValue = undefined;
this.renderStatic = false;

const collectionViewer: CollectionViewer = {
viewChange: this.scrollStrategy.renderedRange$,
};

this.collectionViewer = collectionViewer;
this.connectedDataSource = potentialSignalOrObservableOrDataSource;

this.observables$.next(
potentialSignalOrObservable.connect(collectionViewer),
potentialSignalOrObservableOrDataSource.connect(collectionViewer),
);

this._destroy$.pipe(take(1)).subscribe(() => {
potentialSignalOrObservable.disconnect(collectionViewer);
});
} else if (!isObservable(potentialSignalOrObservable)) {
this.staticValue = potentialSignalOrObservable;
} else if (!isObservable(potentialSignalOrObservableOrDataSource)) {
this.staticValue = potentialSignalOrObservableOrDataSource;
this.renderStatic = true;
} else {
this.staticValue = undefined;
this.renderStatic = false;
this.observables$.next(potentialSignalOrObservable);
this.observables$.next(potentialSignalOrObservableOrDataSource);
}
}

Expand All 99B2 @@ -290,8 +298,7 @@ export class RxVirtualFor<T, U extends NgIterable<T> = NgIterable<T>>
| undefined,
): value is DataSource<T> {
return (
value !== null &&
value !== undefined &&
value != null &&
'connect' in value &&
typeof value.connect === 'function' &&
!(value instanceof ConnectableObservable)
Expand Down Expand Up @@ -677,8 +684,18 @@ export class RxVirtualFor<T, U extends NgIterable<T> = NgIterable<T>>
}
}

/** @internal */
private disconnectDataSource(): void {
if (this.connectedDataSource && this.collectionViewer) {
this.connectedDataSource.disconnect(this.collectionViewer);
this.connectedDataSource = undefined;
this.collectionViewer = undefined;
}
}

/** @internal */
ngOnDestroy() {
this.disconnectDataSource();
this._destroy$.next();
this.templateManager.detach();
}
Expand Down
Loading
0