Infinite Scroll With Ember ListView

Ember ListView is really great. It provides incremental rendering for large lists, and is a little like Collection Views in iOS. Only on-screen objects are reflected in the DOM, vs. each having their own node, and when users scroll the on-screen nodes are updated. You should be using ListView for any large index views.

Out of the box ListView does not support infinite scrolling, and I needed a quick solution for a prototype.

Enter my slightly hacky but workable solution. I’m assuming you know how to subclass ListView, which is required for any modifications. See the docs if you don’t.

Within the view, insert the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export default Ember.VirtualListView.extend({
  //Lazy load more models when less than _refreshAt remain
  //When only _threshold models left, get more data
  _threshold: 10,

  _infiniteScroll: function() {
    var lastIndex      = this.get('_lastEndingIndex'),
        refreshAt      = this.get('_threshold'),
        contentLength  = this.get('content.length');

    if (contentLength - lastIndex < refreshAt) {
      //Get more items, add a 'getting more' wheel if you like
      this.get('controller').send('getMore');
    }
  }.on('scrollYChanged'),
});

ListView exposes two important pieces us:

1) it exposes a scrollYChanged event when a user scrolls; and

2) _lastEndingIndex, while private, updates with the last model accessed. For example, if the 8th model in an array of 10 is being rendered on-screen, _lastEndingIndex would be 8.

The solution is pretty simple. Pick a reload threshold (e.g. at only 5 models left, go and get more) and check on scrollY events.