Closed TripleMap closed 6 years ago
Here's a primitive and inefficient prototype that you can use to learn more about how to create an infinite list of rows:
https://stackblitz.com/edit/angular-1vg9gn?file=app/table-basic-example.ts
On the scroll event, see if the user is seeing a row within 200px of the bottom of the table. If so, add more data to the table's data source.
First step in optimizing this would be to debounce the scroll events since doing this calculation on every scroll event will bog down performance.
@andrewseguin thanks for sharing this. I am trying the same solution with cdk-virtual-scroll
and its working perfectly. Now I am trying incorporate the optimization tip you mentioned above and have below code:
fromEvent(this.virtualViewport.nativeElement, 'scroll')
.pipe(debounceTime(1000))
.subscribe((e: any) => this.onScroll(e));
}
But it doesn't seem to work and throw below error:
ERROR TypeError: Invalid event target
at setupSubscription (fromEvent.js:50)
at Observable._subscribe (fromEvent.js:24)
@TripleMap I built upon @andrewseguin's solution, creating a container that throttles and emits a scroll event while there is more data to load:
https://stackblitz.com/edit/angular-material-data-table-infinite-scroll
I'm using lodash to throttle the scroll event and dynamically assigning a scroll handler to either the host element or the window, based on the element's clientHeight/scrollHeight. This solution works for my use cases, YMMV
@naveedahmed1 Would you mind posting a link to your cdk-virtual-scroll + material table solution? I'd love to use both of those together as well!
@jacobbowdoin please take a look at: https://stackblitz.com/edit/angular-1vg9gn?file=app%2Ftable-basic-example.ts
Something similar to this should help:
<cdk-virtual-scroll-viewport itemSize="50" (scroll)="onScroll($event)" id="list">
<div *cdkVirtualFor="let item of list; let index = index">
</cdk-virtual-scroll-viewport>
onScroll(e) {
const tableViewHeight = e.target.offsetHeight // viewport: ~500px
const tableScrollHeight = e.target.scrollHeight // length of all table
const scrollLocation = e.target.scrollTop; // how far user scrolled
// If the user has scrolled within 200px of the bottom, add more data
const buffer = 200;
const limit = tableScrollHeight - tableViewHeight - buffer;
if (scrollLocation > limit) {
this.dataSource = this.dataSource.concat(ELEMENT_DATA);
}
}
@naveedahmed1 I know it is a bit late, but maybe this helps you.
I've tried the recommended optimization (using debounceTime() at the event subscription) with a mat-table element and it works for me. It is important to setup the subscription in the ngAfterViewInit() method, and that you use the "{read: ElementRef}" option at the @ViewChild-decorated class-variable (that points to the physical table element), i.e.
@ViewChild('table', {read: ElementRef}) public matTableRef: ElementRef;
See my demo here: https://stackblitz.com/edit/mat-table-infinite-scroll
Note: this snipplet demonstrates a very simple bidirectional infinite-scrolling, with a simple memory-preserving array storage, At scrolling, we "load" three virtual pages (with fake data), each of them contains 50 items. Then we re-fill the same array at the next scroll-event.
I don't know if it can help but here is my solution: https://stackblitz.com/edit/angular-mat-table-infinite-scroll-with-sort?file=src%2Fapp%2Fapp.component.ts
No use of cdk virtual scroll just mat-table, data can also be sorted.
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.
feature request:
Does anybody implements infinite scroll to material/cdk table?
What is the expected behavior?
infinite scroll
What is the current behavior?
just update on data change event.
What is the use-case or motivation for changing an existing behavior?
I have more than 10 000 rows. Of course I can use pagination, but it will be much more representative and useful without paginator.
Which versions of Angular, Material, OS, TypeScript, browsers are affected?
angular 5.0.0 material 5.2.0
I have tried to add some new logic to table method renderRows(). It render some rows at specific place by currentIndex. But it looks like big crutch =(