1. #1
    Sencha User
    Join Date
    Nov 2010
    Location
    Ukraine
    Posts
    11
    Vote Rating
    0
    NexusOne is on a distinguished road

      0  

    Default Infinite Scrolling: PageMap asked for range which it does not have

    Infinite Scrolling: PageMap asked for range which it does not have


    When I scroll somewhere and call store.reload() once or twice it's throw "PageMap asked for range which it does not have"

    I've just add "Refresh" button to ext-4.2.0.265/examples/grid/infinite-scroll.html file
    Code:
    Ext.require([
        'Ext.grid.*',
        'Ext.data.*',
        'Ext.util.*',
        'Ext.grid.plugin.BufferedRenderer'
    ]);
    
    
    Ext.onReady(function(){
        Ext.define('ForumThread', {
            extend: 'Ext.data.Model',
            fields: [
                'title', 'forumtitle', 'forumid', 'username', {
                    name: 'replycount',
                    type: 'int'
                }, {
                    name: 'lastpost',
                    mapping: 'lastpost',
                    type: 'date',
                    dateFormat: 'timestamp'
                },
                'lastposter', 'excerpt', 'threadid'
            ],
            idProperty: 'threadid'
        });
    
        // create the Data Store
        var store = Ext.create('Ext.data.Store', {
            id: 'store',
            model: 'ForumThread',
            remoteGroup: true,
            // allow the grid to interact with the paging scroller by buffering
            buffered: true,
            leadingBufferZone: 300,
            pageSize: 100,
            proxy: {
                // load using script tags for cross domain, if the data in on the same domain as
                // this page, an Ajax proxy would be better
                type: 'jsonp',
                url: 'http://www.sencha.com/forum/remote_topics/index.php',
                reader: {
                    root: 'topics',
                    totalProperty: 'totalCount'
                },
                // sends single sort as multi parameter
                simpleSortMode: true,
                // sends single group as multi parameter
                simpleGroupMode: true,
    
                // This particular service cannot sort on more than one field, so grouping === sorting.
                groupParam: 'sort',
                groupDirectionParam: 'dir'
            },
            sorters: [{
                property: 'threadid',
                direction: 'ASC'
            }],
            autoLoad: true,
            listeners: {
    
                // This particular service cannot sort on more than one field, so if grouped, disable sorting
                groupchange: function(store, groupers) {
                    var sortable = !store.isGrouped(),
                        headers = grid.headerCt.getVisibleGridColumns(),
                        i, len = headers.length;
                    
                    for (i = 0; i < len; i++) {
                        headers[i].sortable = (headers[i].sortable !== undefined) ? headers[i].sortable : sortable;
                    }
                },
    
                // This particular service cannot sort on more than one field, so if grouped, disable sorting
                beforeprefetch: function(store, operation) {
                    if (operation.groupers && operation.groupers.length) {
                        delete operation.sorters;
                    }
                }
            }
        });
    
        function renderTopic(value, p, record) {
            return Ext.String.format(
                '<a href="http://sencha.com/forum/showthread.php?t={2}" target="_blank">{0}</a>',
                value,
                record.data.forumtitle,
                record.getId(),
                record.data.forumid
            );
        }
    
        var grid = Ext.create('Ext.grid.Panel', {
            width: 700,
            height: 500,
            collapsible: true,
            title: 'ExtJS.com - Browse Forums',
            store: store,
            loadMask: true,
            selModel: {
                pruneRemoved: false
            },
            multiSelect: true,
            viewConfig: {
                trackOver: false
            },
            features:[{
                ftype: 'grouping',
                hideGroupedHeader: false
            }],
            // grid columns
            columns:[{
                xtype: 'rownumberer',
                width: 50,
                sortable: false
            },{
                tdCls: 'x-grid-cell-topic',
                text: "Topic",
                dataIndex: 'title',
                flex: 1,
                renderer: renderTopic,
                sortable: true
            },{
                text: "Author",
                dataIndex: 'username',
                width: 100,
                hidden: true,
                sortable: true
            },{
                text: "Replies",
                dataIndex: 'replycount',
                align: 'center',
                width: 70,
                sortable: false
            },{
                id: 'last',
                text: "Last Post",
                dataIndex: 'lastpost',
                width: 130,
                renderer: Ext.util.Format.dateRenderer('n/j/Y g:i A'),
                sortable: true,
                groupable: false
            }],
            tbar: [{
                text: 'Refresh',
                handler: function (){
                    store.reload();
                }
            }],
            renderTo: Ext.getBody()
        });
    });
    According to my guesswork method Ext.data.Store.reload has this code
    Code:
            // 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;
    
                waitForReload = function() {
                    if (me.rangeCached(startIdx, endIdx)) {
                        me.loading = false;
                        me.data.un('pageAdded', waitForReload);
                        records = me.data.getRange(startIdx, endIdx);
                        me.fireEvent('load', me, records, true);
                    }
                };
                bufferZone = Math.ceil((me.leadingBufferZone + me.trailingBufferZone) / 2);
    
                // Get our record index range in the dataset
                startIdx = options.start || (count ? me.getAt(0).index : 0);
                endIdx = startIdx + (options.count || (count ? count : me.pageSize)) - 1;
    
                // 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);
    
                // Clear cache (with initial flag so that any listening BufferedRenderer does not reset to page 1).
                me.data.clear(true);
    
                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);
    
                    // Recache the page range which encapsulates our visible records
                    for (i = startPage; i <= endPage; i++) {
                        me.prefetchPage(i, options);
                    }
                }
            } else { ...}
    endPage increase every time when I click refresh button, but according to store.purgePageCount only last pages will be presented in LruCache, so I catch this error

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,014
    Vote Rating
    848
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    I'm not getting that when I check using the code for the next release.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Touch Premium Member
    Join Date
    Apr 2011
    Location
    Southern CA, Orange County
    Posts
    5
    Vote Rating
    0
    KenD2364 is on a distinguished road

      0  

    Default Me too, but totalCount must be a multiple of pageSize

    Me too, but totalCount must be a multiple of pageSize


    I am getting the same error. I traced it down to having the problem only when the page size is a multiple of total count. For instance, if my pageSize = 25, and if the data I load (does not matter if it is in page 1 or page n) is exactly 100 records, when I scroll, I will see the problem. If I have one more or one less, I do not see the problem. Sometimes it reports the error, other times the scrolling gets messed up.

    Maybe the above will help in isolating the problem.

    btw, I am using ExtJs 4.2.1 and buffered store.

    I was able to duplicate the problem (during load anyway) when running the 4.2.1 example, inifinite-scroll-grid-tuner. To keep it simple, set:

    Dataset row count: 100

    buffer store: checked
    pageSize: 25
    trailing buffer zone: 25
    leading buffer zone: 50

    other values, just use the default.

    When you change the pageSize to one off, say 26, it loads without an error.

  4. #4
    Sencha User Tim Toady's Avatar
    Join Date
    Feb 2010
    Location
    Pennsylvania
    Posts
    537
    Vote Rating
    71
    Tim Toady is a jewel in the rough Tim Toady is a jewel in the rough Tim Toady is a jewel in the rough Tim Toady is a jewel in the rough

      0  

    Default


    Ken, I have noticed the same behavior and may look into it if I get a chance.

    The first post sounds like this open ticket: http://www.sencha.com/forum/showthre...l=1#post979464

  5. #5
    Sencha User
    Join Date
    Aug 2013
    Posts
    1
    Vote Rating
    0
    kompas is on a distinguished road

      0  

    Default


    I have exactly the same problem (the one described by KenD2364) - if total count is multiplication of page size, it breaks when showing last page, if I change page size - everything works fine. Looks like simple off-by-one error. Do you know any ticket regarding this problem, or workaround? If not, I'll submit new bug ticket.

  6. #6
    Sencha User
    Join Date
    Aug 2013
    Posts
    7
    Vote Rating
    0
    gmainerd is on a distinguished road

      0  

    Default


    Hi,

    I am using 4.2.1 ExtJS version and I have the same problem in the last page, using page size 100 in the store and total count 1000, 2000, etc (multiple of page size) got the: "PageMap asked for range..." error.<br><br>Regards.

  7. #7
    Sencha User
    Join Date
    May 2013
    Posts
    2
    Vote Rating
    0
    modestemax is on a distinguished road

      0  

    Default


    all these codes don't work for me, after many debugging I wrote this override which solve the problem.
    Code:
    Ext.define('overrides.LruCache', {
    
    
        override: 'Ext.util.LruCache',
    
    
        // private. Only used by internal methods.
        unlinkEntry: function (entry) {
            // Stitch the list back up.
            if (entry) {
                if (this.last && this.last.key == entry.key)
                    this.last = entry.prev;
                if (this.first && this.first.key == entry.key)
                    this.first = entry.next;
    
    
                if (entry.next) {
                    entry.next.prev = entry.prev;
                } else {
                    this.last = entry.prev;
                }
                if (entry.prev) {
                    entry.prev.next = entry.next;
                } else {
                    this.first = entry.next;
                }
                entry.prev = entry.next = null;
            }
        }
    
    
    
    
    });