endash/endash — Issue #34: TableView requesting more records to SparseArray
Author: rvega
Created: 2011-11-23 13:31:24+00:00
State: open

I'm using the latest version of sproutcore master branch with endash's latest tableview. I'm using a SparseArray as the content for the tableView and I'm experiencing the following problem:

I call this.set('content', Core.store.find(SC.Query.remote(Core.Usuario))); to get a list of records from my server. The fetch method in my datasource gets called and I create and populate sparseArray like this:

fetch: function(store, query) {
store.loadQueryResults(query, SC.SparseArray.create({delegate: this, store: store, query: query, rangeWindowSize:20}));
return YES;
},

sparseArrayDidRequestRange: function(sparseArray, range) {
var url = '/foo';
SC.Request.getUrl(url)
.set('isJSON', YES)
.notify(this, this._didFetch, { sparseArray:sparseArray })
.send();
},

_didFetch: function(response, params){
var sparseArray = params.sparseArray;
if(response.status == 200){
var count = response.get('body').cnt;
var content = response.get('body').c;
// ... parse content, get records, get range.
sparseArray.provideLength(count);
var storeKeys = sparseArray.get('store').loadRecords(Core.Usuario, records, ids);
sparseArray.provideObjectsInRange(range, storeKeys);
sparseArray.rangeRequestCompleted(range.start);
}
return YES;
}

When I scroll the table down, the sparseArrayDidRequestRange method gets called and the table is populated correctly. However, when I reach the bottom of the table, the sparseArrayDidRequestRange gets called many more times with ranges that are beyond the size of my dataset ( sparseArray.provideLength(count); ).

I have done a bit of debugging and I hunted down the problem to the reloadIfNeeded(nowShowing, scrollOnly) method in Endash.CollectionFastPath. This method always receives it's second parameter as undefined and the if (!scrollOnly) check that is made within that method always evaluates to true and that's where everything else is triggered and the dataset.fetch method ends up being called with a wrong range.

Now, the reloadIfNeeded method is being called by invokeMethods in SC.ObserverSet. That's as far as my SC-fu can get me.

If I change the if statement I mentioned to if(false), the scrolling and loading works fine, but the table is not refreshed when something other than scrolling happens (clicking to select a row, etc.)