0

I'm doing a project in Angular 2 and I'm getting an issue that makes my pages lose a lot of performance. So, I have a table and everytime I scroll (up or down) it keeps calling one of my functions. This is the one:

.component.ts

entriesToShow(): Array<any>{
    let entries = [];
    let i = 0;
    if(Number(this.startingEntry)+Number(this.numOfEntries) <this.totalEntries)
        this.lastShowingEntry = Number(this.startingEntry)+Number(this.numOfEntries);
    else
        this.lastShowingEntry = this.totalEntries;

    if(this.dataTable != null && this.dataTable.aaData != null){
        for(i = this.startingEntry; i< this.lastShowingEntry; i++){
            entries.push(this.dataTable.aaData[i]);
        }
        this.lastShowingEntry = i;
        return entries;
    }else
        return null;
}

And in my html I got something like this:

<div class="col-md-12" *ngIf="isDataTableAvailable">
     <table id="table-EDIImports" class="table table-bordered display" cellspacing="0">
         <thead>
              <tr>
                   <th><strong>{{ 'POINT_OF_SALE' | translate }}</strong></th>

                    (more fields)

                    <th *ngIf="mode=='EDIT'"></th>
             </tr>
             <tr *ngFor="let obj of entriesToShow()" [ngSwitch]="obj.Status">
                    <th>{{ obj.PointOfSell }}</th>
                    <th *ngIf="obj.LineID == editRowId && selectedField == 'NIF' && mode=='EDIT'">
                        <input type="text" [(ngModel)]="valueToSave" value="{{ obj.NIF }}">
                     </th>
                        (more fields)
              </tr>
           </thead>
           <tbody></tbody>
       </table>
 </div>

Any advice to make my page stop calling entriesToShow() everytime I scroll up/down?

Thank for the help.

EDIT: Removed some extra code

João Silva
  • 531
  • 4
  • 21
  • 40
  • 1
    Possible duplicate of [Prevent a native browser event ( like scroll ) from firing change detection](https://stackoverflow.com/questions/37315781/prevent-a-native-browser-event-like-scroll-from-firing-change-detection) – Nico Van Belle Jul 10 '17 at 11:58

1 Answers1

2

Don't call the entriesToShow() function from your template! It cause's the function to be called every change detection! Instead you should store the data in a variable in your component and the ngFor should iterate over him. .component.ts

        entries:Array<any>;

        ngOnInit(){
           this.entries=this.entriesToShow();
        }
        entriesToShow(): Array<any>{
            let entries = [];
            let i = 0;
            if(Number(this.startingEntry)+Number(this.numOfEntries) <this.totalEntries)
                this.lastShowingEntry = Number(this.startingEntry)+Number(this.numOfEntries);
            else
                this.lastShowingEntry = this.totalEntries;

            if(this.dataTable != null && this.dataTable.aaData != null){
                for(i = this.startingEntry; i< this.lastShowingEntry; i++){
                    entries.push(this.dataTable.aaData[i]);
                }
                this.lastShowingEntry = i;
                return entries;
            }else
                return null;
        }

.html

<div class="col-md-12" *ngIf="isDataTableAvailable">
     <table id="table-EDIImports" class="table table-bordered display" cellspacing="0">
         <thead>
              <tr>
                   <th><strong>{{ 'POINT_OF_SALE' | translate }}</strong></th>

                    (more fields)

                    <th *ngIf="mode=='EDIT'"></th>
             </tr>
             <tr *ngFor="let obj of entries" [ngSwitch]="obj.Status">
                    <th>{{ obj.PointOfSell }}</th>
                    <th *ngIf="obj.LineID == editRowId && selectedField == 'NIF' && mode=='EDIT'">
                        <input type="text" [(ngModel)]="valueToSave" value="{{ obj.NIF }}">
                     </th>
                        (more fields)
              </tr>
           </thead>
           <tbody></tbody>
       </table>
 </div>
Gili Yaniv
  • 3,073
  • 2
  • 19
  • 34
  • Well... that didn't work.. I can't get the data rendered that way... check the img: http://imgur.com/H6qkCIK – João Silva Jul 10 '17 at 13:20
  • Why can't you get the data? What did you try to show me in the image? – Gili Yaniv Jul 10 '17 at 13:24
  • Well... the page will access a database and then load the data, when the html is renderer I don't have any entries yet, I guess thats making the table empty – João Silva Jul 10 '17 at 13:26
  • Did you debuged the code to make sure entriesToShow() doesn't return null or empty array? – Gili Yaniv Jul 10 '17 at 13:29
  • Well, the pagination and number of entries are there, if you see I have 4334 entries, so it isn't null... The method to get the entries work fine, my problem is just everytime I scroll it run the method over and over – João Silva Jul 10 '17 at 13:31
  • The multiple calls happening because you call the function from your template as I said.. If you changed your code as I wrote it should work.. Are you getting any errors in console? Is is possible that you *ngIf returns false? – Gili Yaniv Jul 10 '17 at 13:36
  • I dont have any errors on console, ngif is fine and the method is called only once (I insert a console log inside of it), so I guess it's called after the view is rendered thats why my data doesn't show – João Silva Jul 10 '17 at 13:43
  • Are you using a 3rd party lib for displaying the table? – Gili Yaniv Jul 10 '17 at 13:52
  • No, I'm just getting the data through a webservice of my own. – João Silva Jul 10 '17 at 13:54
  • Strange.. Can you add your full component?) – Gili Yaniv Jul 10 '17 at 14:03
  • I added all my component before the changes made in your post. – João Silva Jul 10 '17 at 14:10
  • I did and I removed it yesterday before going out of work, want me to add it again? – João Silva Jul 11 '17 at 08:39
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/148863/discussion-between-gili-yaniv-and-joao-silva). – Gili Yaniv Jul 11 '17 at 08:50