Günter Zöchbauer's answer is perfect (upvoted). I want to explain a bit about it:
The Zone library that Angular2 uses internally monkey patches a lot of APIs, including the event listener APIs. But this does not include the window/element on<EVENT> properties, maybe because they are considered old and discouraged.
But if you use the addEventListener API, this should work just fine.
Example:
export class SomeClass {
private isInfinitiveScrollLoaderEnabled: boolean;
constructor(private ngZone: NgZone) {
this.isInfinitiveScrollLoaderEnabled = false;
}
ngOnInit() {
window.addEventListener('scroll', (event) => {
if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) {
console.log('Bottom of page');
this.isInfinitiveScrollLoaderEnabled = true;
}
});
}
}
Of course if you can about abstracting away the DOM for use with server rendering or mobile frameworks like NativeScript / ReactNative, you can go for the other valid options
import {DOM} from 'angular2/platform/common_dom.dart';
DOM
.getGlobalEventTarget('window')
.addEventListener('message', function, false);
Or
@HostListener('window:scroll', ['$event'])`
which looks the most declarative to me.
Both as Günter Zöchbauer mentioned.
If you don't care about these rendering considerations, they might look foreign or so in your code. It's your call either way and should be fine.
Whatever you choose, I'd stay away from the this.ngZone.run() option, because it brings bad memories from the days of $scope.$apply(), although admittedly it's not as bad.