Sagi
Sagi

Reputation: 1612

implement infinite scroller in angular2

I would like to implement infinite scrolling for an *ng-for of DIVs in angular2 component. For this I need to somehow hook to the window onScroll event via angular method. Then in angular I will be able to load more items into the data items array when user has scrolled pass some point of the page.

Anyone has ideas how to hook to the window.scroll event from angular (inside ng2 component)?

Upvotes: 14

Views: 18228

Answers (3)

Eiks
Eiks

Reputation: 48

component.html

<div (scroll)="onScroll($event)">
    //Content
</div>

Now i just used the $event.target properties scrollTopMax and scrollTop:

component.ts

onScroll(event: any): void {
   let elementHeight = event.target.scrollTopMax;
   let scrollPosition = event.target.scrollTop;
   if( elementHeight - scrollPosition < 100) {
       //add Content
   }
}

Of course you will need some function checking if new content is already rendered. If not the onScroll() function will be called much too often.

In my case i insert other component with *ngFor and created and @Output to notify the parent about a finished rendering.

child.component.ts

@Output()
rendered = new EventEmitter();

ngAfterViewChecked() {
    this.rendered.emit(<uniqueIdentifier>);
}

component.html

<div (scroll)="onScroll($event)">
    <child *ngFor="element in displayedElement"
        (rendered)="elementRendered($event)">
    </child>

component.ts

elements: any;
displayedElements: any[];
renderedElements: new Set();

addElements(): void {
    /////
}

elementRendered(<uniqueIdentifier>: any) {
    this.renderedElements.add(<uniqueIdentifier>);
}

onScroll(event: any): void {
    if( this.displayedElements.length == this.renderedElements.size) {
        let elementHeight = event.target.scrollTopMax;
        let scrollPosition = event.target.scrollTop;
        if( elementHeight - scrollPosition < 100) {
            this.addElements();
        }
    }
}

Upvotes: 1

Ashish Sharma
Ashish Sharma

Reputation: 679

You can use @HostListener to detect Scrolling. This is how I have done this

 export class AppComponent {

  @HostListener('window:scroll', ['$event'])
    onScroll($event: Event): void {
    console.log("On Scroll");
    //Logic To Check whether we are bottom of the page
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
      console.log("On Scroll Down");
      //Write logic here for loading new content.
    }
  }

}

Hope this will help you :)

Upvotes: 11

alexpods
alexpods

Reputation: 48505

Use (target:event)="handler()" notation for listening to global events. You can use window, document or body as a target. For your case it will be (window:scroll)="onScroll($event)". See this plunk.

import {Component} from 'angular2/core'

@Component({
  selector: 'my-app',
  template: `
    <div (window:scroll)="onScroll($event)">
      <h1>Hello Angular2</h1>
      ...
    </div>
  `,
})
export class App {

  onScroll(event) {
    console.log('scroll event', event);
  }
}

Upvotes: 29

Related Questions