ExtJs4.2示例中infinite-scroll出现PageMap asked for range which it does not have错误及解决

来源:互联网 发布:搜客软件下载 编辑:程序博客网 时间:2024/05/17 08:58

ExtJS的表格做的非常强大,但是ExtJS的源码相当庞大当框架内部出现问题的时候非常难查找到解决办法。最近因为学习的需要,我们在使用ExtJSP制作公司内部的管理系统,但是在使用ExtJS自带的examples中的gird中的infinite-scroll时,却出现了“Ext.data.PageMap.getRange(): PageMap asked for range which it does not have”的错误,最终只有通过重载它自身的方法才解决问题。

环境描述:ext-4.2.1.883,谷歌浏览器调试工具(火狐浏览器需要使用fireBug)

错误描述:由于引用ExtJSP不同的包会出现不同的提示这里就以ext-all-dev.js和ext-dev.js两种不同的引用方式来说明。

当引用ext-all-dev.js时错误如下图描述:


当引用ext-dev.js时错误如下图描述:


两种引用方式都在说明一个问题:[E] Ext.data.PageMap.getRange(): PageMap asked forrange which it does not have。

解决办法:通过debug Ext的代码最终查找到 ext-4.2.1.883/src/view/Table.js 中的方法“renderRow”出错(这是引用完整ExtJS代码ext-dev.js时的情况,如果引用了ext-all-dev.js,那么“renderRow”在150317行),这是类'Ext.view.Table'中的一个方法。

通过重载Ext.view.Table中的方法解决问题,代码如下:

Ext.override(Ext.view.Table, {renderRow: function(record, rowIdx, out) {        var me = this,            isMetadataRecord = rowIdx === -1,            selModel = me.selModel,            rowValues = me.rowValues,            itemClasses = rowValues.itemClasses,            rowClasses = rowValues.rowClasses,            cls,            rowTpl = me.rowTpl;        // Set up mandatory properties on rowValues        rowValues.record = record;        rowValues.recordId = record.internalId;        rowValues.recordIndex = rowIdx;        rowValues.rowId = me.getRowId(record);        rowValues.itemCls = rowValues.rowCls = '';        if (!rowValues.columns) {            rowValues.columns = me.ownerCt.columnManager.getColumns();        }        itemClasses.length = rowClasses.length = 0;        // If it's a metadata record such as a summary record.        // So do not decorate it with the regular CSS.        // The Feature which renders it must know how to decorate it.        if (!isMetadataRecord) {            itemClasses[0] = Ext.baseCSSPrefix + "grid-row";            if (selModel && selModel.isRowSelected) {            //正是这里出错,原来的方法是            //selModel.isRowSelected(rowIdx + 1)            //从而导致PageMap的越界错误                if (selModel.isRowSelected(rowIdx)) {                    itemClasses.push(me.beforeSelectedItemCls);                }                if (selModel.isRowSelected(record)) {                    itemClasses.push(me.selectedItemCls);                }            }            if (me.stripeRows && rowIdx % 2 !== 0) {                rowClasses.push(me.altRowCls);            }            if (me.getRowClass) {                cls = me.getRowClass(record, rowIdx, null, me.dataSource);                if (cls) {                    rowClasses.push(cls);                }            }        }                if (out) {            rowTpl.applyOut(rowValues, out);        } else {            return rowTpl.apply(rowValues);        }    }});

在重载这个方法之后,可能会影响其它的grid,但是在目前的使用中其它grid正常运行,没有出现任何问题!

其它问题:关于这个问题有许多人都在这个版本中遇到,但是据说在5.0之后的收费版中已经不存在了。

可以参考以下两篇文章的描述:

https://www.sencha.com/forum/showthread.php?264733-Grid-with-Infinite-Scroling-in-4.2.1-Reload-Function&p=979464&viewfull=1

http://www.4byte.cn/question/601040/get-rid-of-pagemap-asked-for-range-which-it-does-not-have-exception.html

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

测试代码(Java)

index.jsp:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>Welcome</title>    <link rel="stylesheet" type="text/css" href="ext42/resources/css/ext-all.css" />    <script type="text/javascript" src="ext42/ext-all-dev.js"></script>    <script type="text/javascript" src="ext42/locale/ext-lang-zh_CN.js"></script>    <script type="text/javascript" charset="UTF-8" src="js/test.js"></script>  </head>  <body>  </body></html>

test.js(也就是把ext-4.2.1.883/examples/grid/infinite-scroll.js做了简化):

Ext.require([    'Ext.grid.*',    'Ext.data.*',    'Ext.util.*',    'Ext.grid.plugin.BufferedRenderer']);Ext.onReady(function(){    Ext.override(Ext.view.Table, {        renderRow: function(record, rowIdx, out) {            var me = this,                isMetadataRecord = rowIdx === -1,                selModel = me.selModel,                rowValues = me.rowValues,                itemClasses = rowValues.itemClasses,                rowClasses = rowValues.rowClasses,                cls,                rowTpl = me.rowTpl;                // Set up mandatory properties on rowValues            rowValues.record = record;            rowValues.recordId = record.internalId;            rowValues.recordIndex = rowIdx;            rowValues.rowId = me.getRowId(record);            rowValues.itemCls = rowValues.rowCls = '';            if (!rowValues.columns) {                rowValues.columns = me.ownerCt.columnManager.getColumns();            }                itemClasses.length = rowClasses.length = 0;                // If it's a metadata record such as a summary record.            // So do not decorate it with the regular CSS.            // The Feature which renders it must know how to decorate it.            if (!isMetadataRecord) {                itemClasses[0] = Ext.baseCSSPrefix + "grid-row";                if (selModel && selModel.isRowSelected) {                    //正是这里出错,原来的方法是                    //selModel.isRowSelected(rowIdx + 1)                    //从而导致PageMap的越界错误                    if (selModel.isRowSelected(rowIdx)) {                        itemClasses.push(me.beforeSelectedItemCls);                    }                    if (selModel.isRowSelected(record)) {                        itemClasses.push(me.selectedItemCls);                    }                }                    if (me.stripeRows && rowIdx % 2 !== 0) {                    rowClasses.push(me.altRowCls);                }                    if (me.getRowClass) {                    cls = me.getRowClass(record, rowIdx, null, me.dataSource);                    if (cls) {                        rowClasses.push(cls);                    }                }            }                        if (out) {                rowTpl.applyOut(rowValues, out);            } else {                return rowTpl.apply(rowValues);            }        }    });        Ext.define('ForumThread', {        extend: 'Ext.data.Model',        fields: ['key', 'value'],        idProperty: 'key'    });    // 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: 0,        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: 'ajax',            url: 'DataServer',            reader: {                root: 'data',                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: 'key',            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;                }            }        }    });    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: 100,            sortable: false        },{            text: "key",            dataIndex: 'key',            width: 100,            sortable: true        },{            text: "value",            dataIndex: 'value',            align: 'center',            flex: 1,            sortable: false        }],        renderTo: Ext.getBody()    });});

DataServer.java(服务器端servlet代码):

package com.ext.servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class DataServer extends HttpServlet {/** * Constructor of the object. */public DataServer() {super();}/** * Destruction of the servlet. <br> */public void destroy() {super.destroy(); // Just puts "destroy" string in log// Put your code here}/** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. *  * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {PrintWriter out = response.getWriter();String pageStr = request.getParameter("page");String startStr = request.getParameter("start");String limitStr = request.getParameter("limit");pageStr = pageStr==null || pageStr.equals("") ? "0":pageStr;startStr = startStr==null || startStr.equals("") ? "0":startStr;limitStr = limitStr==null || limitStr.equals("") ? "100":limitStr;int page = Integer.valueOf(pageStr);int start = Integer.valueOf(startStr);int limit = Integer.valueOf(limitStr);int count = 600;StringBuffer buffer = new StringBuffer();buffer.append("{'totalCount':'"+count+"','data':[");for (int i=start; i< start+limit; i++){buffer.append("{'key':'key-"+i+"','value':'val-"+i+"'},");}buffer.delete(buffer.lastIndexOf(","), buffer.length());buffer.append("]}");out.write(buffer.toString());//out.write("<html>sadf</html>");out.flush();out.close();}/** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. *  * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {this.doGet(request, response);}/** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */public void init() throws ServletException {// Put your code here}}



0 0