ExtJS Grid renders more rows than specified in pagesize

我的梦境 提交于 2019-12-10 19:38:29

问题


I have implemented an infinite grid based on the example given by Sencha. Basically the proxy fetches json files using jsonp and populates the grid. I want the grid size to be 10 and I want the proxy to make subsequent requests only when the user scrolls down closer to the 10th record. Each record takes sufficient space vertically in the grid view, and only about 5 records can be seen without scrolling (on my 14 inch laptop with a resolution of 1366 x 768). I have set the pagesize to be 10, and my expectation is that the grid refreshes only when I scroll down beyond the visible records. However, the grid loads all the data (50 records in all) by making 5 individual requests even without scrolling. Here's the code:

Ext.require([
    'Ext.grid.*',
    'Ext.data.*',
    'Ext.util.*',
    'Ext.grid.plugin.BufferedRenderer'
]);

Ext.onReady(function() {
    Ext.define('ContentModel', {
        extend : 'Ext.data.Model',
        fields : [ 'content_id', 'content' ],
        idProperty: 'content_id'
    });

    var store = Ext.create('Ext.data.Store', {
        id : 'store',
        model : 'ContentModel',
        buffered: true,
        pageSize: 10,
        proxy : {
            type : 'jsonp',
            url : 'http://website.com/Top1.json',
            reader: {
                root: 'contents',
                totalProperty: 'totalCount'
            }
        },
        autoLoad : true
    });

    var grid = Ext.create('Ext.grid.Panel', {
        renderTo : Ext.getBody(),
        width : '100%',
        height : '100%',
        title : 'Reader Panel',
        id : 'reader',
        store : store,
        columns : [ {
            id : 'content_id',
            text : 'Content ID',
            dataIndex : 'content_id',
            width : '10%'
        },
        {
            id : 'content',
            text : 'Content',
            dataIndex : 'content',
            width : '90%'
        } ]
    });

    Ext.define('JSONP Proxy', {
        override: 'Ext.data.proxy.JsonP',
        buildUrl: function(request) {
            var me = this, url = this.getUrl(request);
            console.log(url);
            request.url = 'http://website.com/Top' + request.params.page + '.json';
            return me.callParent([request]);
        }
    });

});

And the content of the json files are:

Top1.json:

Ext.data.JsonP.callback1({"totalCount":"50", "contents":[{"content_id" : 1, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 2, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 3, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 4, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 5, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 6, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 7, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 8, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 9, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"},{"content_id" : 10, "content" : "<div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br><div> Hello World 1</div><br>"}]});

The other json files follow the same format, with unique content ids, and have the right callbacks (callback2, callback3, callback4 and callback5).

Can someone tell me why all 5 jsonp requests get fired straight away, than waiting for me to scroll?

Thanks, Prathap


回答1:


Thanks everyone for pointing me in the right direction. So, here's what worked finally:

Ext.require([
    'Ext.grid.*',
    'Ext.data.*',
    'Ext.util.*',
    'Ext.grid.plugin.BufferedRenderer'
]);

Ext.onReady(function() {
    Ext.define('ContentModel', {
        extend : 'Ext.data.Model',
        fields : [ 'content_id', 'content' ],
        idProperty: 'content_id'
    });

    var store = Ext.create('Ext.data.Store', {
        id : 'store',
        model : 'ContentModel',
        buffered: true,
        pageSize: 10,
        trailingBufferZone: 5,
        leadingBufferZone: 5,
        purgePageCount: 0,
        scrollToLoadBuffer: 10,
        proxy : {
            type : 'jsonp',
            url : 'http://website.com/Top' + 0 + '.json',
            reader: {
                root: 'contents',
                totalProperty: 'totalCount'
            }
        },
        autoLoad : true
    });

    var grid = Ext.create('Ext.grid.Panel', {
        renderTo : Ext.getBody(),
        width : '100%',
        height : '100%',
        title : 'Reader Panel',
        id : 'reader',
        store : store,
        plugins : [{
            ptype: 'bufferedrenderer',
            trailingBufferZone: 5,
            leadingBufferZone: 5,
            scrollToLoadBuffer: 10,
            onViewResize: function(view, width, height, oldWidth, oldHeight) {
                // Only process first layout (the boxready event) or height resizes.
                if (!oldHeight || height !== oldHeight) {
                    var me = this,
                        newViewSize,
                        scrollRange;

                    // View has rows, delete the rowHeight property to trigger a recalculation when scrollRange is calculated
                    if (view.all.getCount()) {
                        // We need to calculate the table size based upon the new viewport size and current row height
                        delete me.rowHeight;
                    }
                    // If no rows, continue to use the same rowHeight, and the refresh handler will call this again.

                    // Calculates scroll range. Also calculates rowHeight if we do not have an own rowHeight property.
                    // That will be the case if the view contains some rows.
                    scrollRange = me.getScrollHeight();
                    //newViewSize = Math.ceil(height / me.rowHeight) + me.trailingBufferZone + me.leadingBufferZone;
                    newViewSize = 18;
                    me.viewSize = me.setViewSize(newViewSize);
                    me.stretchView(view, scrollRange);
                }
            }
        }],
        columns : [ {
            id : 'content_id',
            text : 'Content ID',
            dataIndex : 'content_id',
            width : '10%'
        },
        {
            id : 'content',
            text : 'Content',
            dataIndex : 'content',
            width : '90%'
        } ]
    });

    Ext.define('JSONP Proxy', {
        override: 'Ext.data.proxy.JsonP',
        buildUrl: function(request) {
            var me = this, url = this.getUrl(request);
            console.log(url);
            request.url = 'http://website.com/Top' + request.params.page + '.json';
            return me.callParent([request]);
        }
    });

});

The trick was to set the buffer settings right in both the store and the grid's bufferedrenderer plugin, and overriding the onViewResize method of the plugin. The ViewSize property of the bufferedrenderer was getting computed based on the rowheight, which for some reason was always its default value of 21, and hence resulted in a ViewSize of 60, which is greater than the total number of records in the server (50). This resulted in all the rows being fetched right away. Once I overrode the viewsize property to 18, the viewsize changed correspondingly and now I have only 30 records fetched the first time. And on-demand loading works perfectly on scrolling as well :)




回答2:


You need to set the right values for leadingBufferZone and trailingBufferZone to get the correct number of records.




回答3:


You are using buffered config. If buffered is enabled store loads 5 more pages into prefetch cache by default. In order to change number of prefectched pages use purgePageCount config.



来源:https://stackoverflow.com/questions/15660870/extjs-grid-renders-more-rows-than-specified-in-pagesize

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!