14

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)?

2
  • 1
    (scroll)="update($event)" on the element in your template you want to get scroll notifications should do what you want, no? Commented Dec 28, 2015 at 15:52
  • Tried the following, but doesn't work <div style="height: 100%" (scroll)="onScroll($ev);"> <div *ng-for="#row of rows"></div> </div> the onScroll(ev) function wont get called at all on component. Commented Dec 28, 2015 at 16:47

3 Answers 3

29

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);
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

This does work but how do you get the amount you've scrolled. event.scrollY == 57 kinda thing?
@LukeDupin try window.scrollY. That's what worked for me.
Not working in my case. I am applying this to a div inside my application which is built in ng2-material design. Problem is (window:scroll) doesnot fire in my case @alexpods
im new in angular, and i don't understand, anybody can help me to implement this?
11

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 :)

Comments

1

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();
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.