PDA

View Full Version : [CLOSED] buffered store reload() various problems



siq
6 Dec 2013, 3:21 AM
Ext version tested:

Ext 4.2.2.1144
Hello.

The reload() method on buffered store will try to prefetch an additional non-existent page. This is because the code does not check the real count. Consider a buffered store, with nr. of records <100, pagesize=100, trailing=100,leading=100:

reload: function(options) {
[skip]
bufferZone = Math.ceil((me.leadingBufferZone + me.trailingBufferZone) / 2);//100
[skip]
endIdx = startIdx + (options.count || me.pageSize) - 1; //endIdx on first page will be 0+100-1=99
[skip]
endPage = me.getPageFromRecordIndex(endIdx + bufferZone); //<-- 99+100=199, which results in non existant page 2
[skip]
for (i = startPage; i <= endPage; i++) {
me.prefetchPage(i, options);
}
[skip]


Also, the reload() method does not fire 'datachanged' and 'refresh' events. So, if the json data changes, and the store reload()'s , any grid depending on this data will not refresh.

Fiddle: https://fiddle.sencha.com/#fiddle/208

My temporary override for these 2 problems:



Ext.override(Ext.data.Store, {
reload: function (options) {
var me = this,
startIdx,
endIdx,
startPage,
endPage,
i,
waitForReload,
bufferZone,
records;


if (!options) {
options = {};
}


// If buffered, we have to clear the page cache and then
// cache the page range surrounding store's loaded range.
if (me.buffered) {


// So that prefetchPage does not consider the store to be fully loaded if the local count is equal to the total count
delete me.totalCount;


// Clear cache (with initial flag so that any listening BufferedRenderer does not reset to page 1).
me.data.clear(true);


waitForReload = function () {
if (me.rangeCached(startIdx, endIdx)) {
me.loading = false;
me.data.un('pageAdded', waitForReload);
records = me.data.getRange(startIdx, endIdx);
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
me.fireEvent('load', me, records, true);
}
};
bufferZone = Math.ceil((me.leadingBufferZone + me.trailingBufferZone) / 2);


// Get our record index range in the dataset
if (!me.lastRequestStart) {
startIdx = options.start || 0;
endIdx = startIdx + (options.count || me.pageSize) - 1;
} else {
startIdx = me.lastRequestStart;
endIdx = me.lastRequestEnd;
}


// Calculate a page range which encompasses the Store's loaded range plus both buffer zones
startPage = me.getPageFromRecordIndex(Math.max(startIdx - bufferZone, 0));
endPage = me.getPageFromRecordIndex(endIdx + bufferZone);


if (me.fireEvent('beforeload', me, options) !== false) {
me.loading = true;


// Wait for the requested range to become available in the page map
// Load the range as soon as the whole range is available
me.data.on('pageAdded', waitForReload);

me.on('prefetch', function(store, records, successful, op) {
if (successful) {
if (me.getTotalCount() > 0) {
endPage = Math.min(endPage,me.getPageFromRecordIndex(me.getTotalCount()-1));
for (i = startPage + 1; i <= endPage; ++i) {
me.prefetchPage(i, options);
}
}
}
}, null, {single: true});
me.prefetchPage(startPage, options);

// Recache the page range which encapsulates our visible records
//for (i = startPage; i <= endPage; i++) {
// me.prefetchPage(i, options);
//}
}
} else {
return me.callParent(arguments);
}
}
});

Gary Schlosberg
10 Dec 2013, 2:38 PM
Thanks for the report! I have opened a bug in our bug tracker.