-
-
Notifications
You must be signed in to change notification settings - Fork 269
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
feat(angular-virtual): add Angular adapter #726
base: main
Are you sure you want to change the base?
Conversation
Adds an Angular adapter: - [x] Supports Angular >=17 - [x] Signal-based API - [x] Packaged with ng-packagr - [x] Examples - [x] Works with required input signals - [x] Works with OnPush change detection
Nice, maybe we'll ship 2 new TanStack Angular adapters this week. The Table one should ship in the next few days. |
Hi! At this point I'm mostly just looking for some intent to move forward by the project maintainers as well as feedback from the community. I don't necessarily expect this to be merged as-is, though it is fully functional. This began as a weeknight project inspired by a tweet and before long I had implemented all the examples and fell in love with it. The API and its implementation are heavily inspired by Angular Query and the upcoming Angular Table. There are some specific areas of the API that I would love community feedback on. For example, the adapter replaces the scrollElement = viewChild<ElementRef<HTMLDivElement>>('scrollElement')
// current implementation
virtualizer = injectVirtualizer(() => ({ scrollElement: this.scrollElement() })
// theoretical implementation that matches the core API
virtualizer = injectVirtualizer(() => ({ getScrollElement: () => this.scrollElement()?.nativeElement }) This is currently the only property from the core headerIsSticky = input.required<boolean>()
virtualizer = injectVirtualizer(() => ({
rangeExtractor: (range: { min: number, max: number }) =>
// oops! this won't be re-ran when `this.headerIsSticky()` changes!
this.headerIsSticky() && range.min > 0
? [0, ...defaultRangeExtractor(range)]
: defaultRangeExtractor(range)
})
// you have to do this instead:
headerIsSticky = input.required<boolean>()
virtualizer = injectVirtualizer(() => ({
// rangeExtractor is recreated whenever this.headerIsSticky() changes
rangeExtractor: this.headerIsSticky()
? (range: { min: number, max: number }) => range.min > 0
? [0, ...defaultRangeExtractor(range)]
: defaultRangeExtractor(range)
: defaultRangeExtractor
}) This exact issue (callbacks that close over signals are not reactive) is present in Angular Query as well, and it's not necessarily a dealbreaker, but I can imagine an API where the options object is static (i.e., it's not recreated), but instead each property on it is (optionally?) a signal. For the TS wizards, think something like this (simplified): type AngularVirtualizerOptions = { [K in keyof VirtualizerOptions]: Signal<VirtualizerOptions[K]> } for example: virtualizer: injectVirtualizer({ // no callback, just a {}
// pass signals directly for everything
data: this.data,
count: computed(() => this.data().length),
size: computed(() => this.big() ? ((index) => 250) : ((index) => 100)),
// functions accept signal parameters and expect signal return values
rangeExtractor: (range: Signal<{ min: number; max: number }>) => computed(() =>
// because `rangeExtractor` must return signal, you don't have to remember to hoist signal invocations out of the callback
this.headerIsSticky() && range().min > 0
? [0, ...defaultRangeExtractor(range)]
: defaultRangeExtractor(range))
}) The adapter could easily convert this into the shape that the core Virtualizer needs. Are these terrible ideas? Awesome improvements? If you have thoughts on any of these examples or anything else, please share them! |
Add devcontainer.json to all Angular examples so they run in a container. Updates the Table example to use TanStack Angular Table
The |
☁️ Nx Cloud ReportCI is running/has finished running commands for commit aa61434. As they complete they will appear below. Click to see the status, the terminal output, and the build insights. 📂 See all runs for this CI Pipeline Execution
Sent with 💌 from NxCloud. |
Any further updates? |
Will try to find some time this week, as not that up to date with angular, need to go through comments made by @garrettld |
Adds an Angular adapter:
StackBlitz playground: https://stackblitz.com/edit/stackblitz-starters-sd2s4h?file=src%2Frow-virtualizer-fixed.component.ts