ExtJS Grid呈现的行多于pagesize中指定的行 [英] ExtJS Grid renders more rows than specified in pagesize

查看:99
本文介绍了ExtJS Grid呈现的行多于pagesize中指定的行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经基于Sencha给出的示例实现了无限网格.基本上,代理使用jsonp获取json文件并填充网格.我希望网格大小为10,并且我希望代理仅在用户向下滚动到第10条记录时才发出后续请求.每个记录在网格视图中垂直占据足够的空间,并且在不滚动的情况下只能看到大约5条记录(在我的14英寸笔记本电脑上,分辨率为1366 x 768).我已将pagesize设置为10,我的期望是,只有当我向下滚动到可见记录之外时,网格才会刷新.但是,即使没有滚动,网格也会通过发出5个单独的请求来加载所有数据(总共50条记录).这是代码:

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]);
        }
    });

});

并且json文件的内容是:

And the content of the json files are:

Top1.json:

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>"}]});

其他json文件采用相同的格式,具有唯一的内容ID,并具有正确的回调(callback2,callback3,callback4和callback5).

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

有人能告诉我为什么所有5个jsonp请求都立即被触发,而不是等待我滚动吗?

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

谢谢, Prathap

Thanks, Prathap

推荐答案

感谢大家为我指出正确的方向.所以,这是最后起作用的东西:

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]);
        }
    });

});

诀窍是在商店和网格的bufferedrenderer插件中同时设置缓冲区设置,并覆盖插件的onViewResize方法.基于行高计算bufferedrenderer的ViewSize属性,出于某种原因,该行的默认值始终为21,因此导致ViewSize为60,该值大于服务器中的记录总数(50) .这导致立即获取所有行.一旦将viewsize属性改写为18,viewsize就会相应更改,现在我第一次只有30条记录.按需加载也可以完美地在滚动中工作:)

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 :)

这篇关于ExtJS Grid呈现的行多于pagesize中指定的行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆