2

I am trying to implement a lazy load for a large set of data with primeng <p-datatable>. I have done everything documented on the official site, however I could not make it work.

The onLazyLoad callback runs only once at the time of loading the table. It doesn't trigger on each scroll as expected.

<div style="max-height:300px; border:1px solid black;overflow-y:auto">
      <p-dataTable #pocListref [value]="data" rowHover="true" [(selection)] = "selectedData" scrollable="true" scrollHeight="200px" [rows]="4"
      [style]="{'margin-top':'30px'}"  [paginator]="true" [rowsPerPageOptions]="[5,10,20]"
        [lazy]="true" [totalRecords]="totalRecords" (onLazyLoad)="lazyLoad($event)">
        <p-column header="Id">
        <ng-template pTemplate="body" let-index="rowIndex">
            {{index}}
        </ng-template>
        </p-column>
        <p-column  selectionMode="multiple" [style]="{'width':'5%'}"></p-column>
        <p-column field="name" header="Name"[sortable]="true"></p-column>
        <p-column field="age" header="Age" [sortable]="true"></p-column>
        <p-column field="company" header="Company" [sortable]="true"></p-column>
      </p-dataTable>
  </div>

The same works fine with the paginator implementation. I have noticed that it works with paginator only if I do not use virtualScroll attribute, which makes sense, but somehow virtualScroll doesn't make any effect on scrolling.

I know there is already a similar question but it is still answered.

Has someone used the virtual scroll successfully with lazy loading. Any suggestions will be useful.

Saurabh Tiwari
  • 4,632
  • 9
  • 42
  • 82

3 Answers3

5

Try like this my example :

here is my updated code without paginator and using virtualScroll

<p-dataTable [value]="resultsArr" scrollable="true" scrollHeight="100px" [rows]="4" virtualScroll="virtualScroll" [style]="{'margin-top':'30px'}" [lazy]="true" [totalRecords]="results.length" (onLazyLoad)="lazyLoad($event)">
<p-column header="Id">
<ng-template pTemplate="body" let-index="rowIndex">
    {{index}}
</ng-template>
</p-column>
<p-column  selectionMode="multiple" [style]="{'width':'5%'}"></p-column>
<p-column field="name" header="Name"[sortable]="true"></p-column>
<p-column field="age" header="Age" [sortable]="true"></p-column>
<p-column field="company" header="Company" [sortable]="true"></p-column>
</p-dataTable>

component.ts

export class Component {
    private results: Array<any> = []; // have 15+ objects in this array
    private resultsArr: Array<any> = [];

constructor() {
    this.results = [{
        name: "david",
        age: 26,
        company: "XYz Company"
    }, {
        name: "david",
        age: 26,
        company: "XYz Company"
    }, {
        name: "david",
        age: 26,
        company: "XYz Company"
    }, {
        name: "david",
        age: 26,
        company: "XYz Company"
    }, {
        name: "david",
        age: 26,
        company: "XYz Company"
    }, {
        name: "david",
        age: 26,
        company: "XYz Company"
    }]
}

    lazyLoad(event: any) {
        setTimeout(() => {
            if (this.results) {
                this.resultsArr = this.results.slice(event.first, (event.first + event.rows));
            }
        }, 250);
    }
}

component.html

<p-dataTable [value]="resultsArr" [lazy]="true" [totalRecords]="results.length" [responsive]="true"
             [paginator]="true" (onLazyLoad)="lazyLoad($event)" [rows]="5" [filterDelay]="500"
             [rowsPerPageOptions]="[5,10,20]" sortField="first_name" [sortOrder]="1">
  <p-column field="id" header="#" [sortable]="true" styleClass="columnId" [filter]="true"></p-column>
  <p-column field="first_name" header="First Name" [sortable]="true"></p-column>
  <p-column field="last_name" header="Last Name" [sortable]="true"></p-column>
</p-dataTable>
Chandru
  • 10,864
  • 6
  • 38
  • 53
  • I couldn't check this yet but I see your solution uses pagination. I do not want to have a paginator rather I want the same behaviour on scroll – Saurabh Tiwari Sep 19 '17 at 13:08
  • No not yet. the issue is that the table do not give any event on scroll. – Saurabh Tiwari Sep 19 '17 at 13:13
  • important : [totalRecords]= your response array of length value and [value] taken only slice in the lazyLoad method – Chandru Sep 19 '17 at 13:33
  • Yup..this is what I am doing too. As mentioned the lazyLoad function invokes just once on load and never thereafter. Were you able to make this work. If yes, a plunker would be a great help. Or try editing this plunker http://plnkr.co/edit/BZ607W2zY4V6DpR3NavP?p=preview – Saurabh Tiwari Sep 19 '17 at 15:36
  • This is my example plunker link https://plnkr.co/edit/jwpbEhqAP27KlWZ8EO5W?p=preview using lazyScroll event its working perfectly. may be the problem is your primeng npm version. am used primeng": "^4.2.1" so updated your project check it. – Chandru Sep 19 '17 at 17:28
  • I guess the issue is with the version, because in your code I can at least see the method triggering on scroll. However, ideally your table should display 50000 rows while it just displays 39 rows only. If I change the totalRecords to 50000, it starts displaying multiple rows however the whole table disappears after a while. – Saurabh Tiwari Sep 20 '17 at 13:02
  • With the abpboilerplate and aspnetzero i was able to use your table properties and finagle them a bit, thanks! – Don Thomas Boyle Jun 20 '18 at 19:28
0

I had more or less the same problem, which I fixed after lots of struggling. when I was working on this, I figured out that if scroll the horizontal bar to the left it renders the content, so I added the below code at the end of my codes, It's like a bad workaround but I needed to fix that so I ended up with the below workaround!!

 const scroll = document.getElementsByClassName("p-scroller-inline")[0] as HTMLElement;
            if (scroll) {
              scroll.scrollLeft += 1;
            }
Hamid
  • 761
  • 7
  • 18
-1

i use the p-table, but i think it is the same way it does the lazyloading as p-datatable. i fix this problem with a trick. i set the totalRecords as a large number or a number much larger than your current data(e.g. the current data's length is 500, set the totalRecords as 1000), then the lazyloading will be triggered on each scroll