最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Get rid of "PageMap asked for range which it does not have" exception - Stack Overflow

programmeradmin0浏览0评论

Occassionally I get the exception "PageMap asked for range which it does not have" from my Ext Js 4.2.1 infinite scrolling grid. It is raised in data/PageMap.js on line 211. Of course one should not ask for non-existing entries, but this is sometimes done by the framework itself. Seems to be somehow connected to adding/removing records or reloading the grid. There are already some threads on this topic in the Sencha forum, e.g. this, but no killer solution or bugfix was proposed yet.

Meanwhile, I have to keep this exception from the users' eyes. What would be a good way to do so? Tricky thing is that it is sometimes provoked just by the user moving the scrollbar, so there is no single line of my code directly involved.

Occassionally I get the exception "PageMap asked for range which it does not have" from my Ext Js 4.2.1 infinite scrolling grid. It is raised in data/PageMap.js on line 211. Of course one should not ask for non-existing entries, but this is sometimes done by the framework itself. Seems to be somehow connected to adding/removing records or reloading the grid. There are already some threads on this topic in the Sencha forum, e.g. this, but no killer solution or bugfix was proposed yet.

Meanwhile, I have to keep this exception from the users' eyes. What would be a good way to do so? Tricky thing is that it is sometimes provoked just by the user moving the scrollbar, so there is no single line of my code directly involved.

Share Improve this question edited Jul 17, 2013 at 11:19 Christoph asked Jul 17, 2013 at 6:39 ChristophChristoph 1,02311 silver badges24 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 4

I found the root cause to be that when it's rendering rows, it determines if it's before a selected row. If it's working on the last row, it still looks for row + 1. (Ext.view.Table:931 in 4.2.1)

My simple solution is to just make it return false:

Ext.override(Ext.selection.RowModel,
{
    isRowSelected: function (record, index)
    {
        try
        {
            return this.isSelected(record);
        }
        catch (e)
        {
            return false;
        }
    }
});

Christoph,

I have similar troubles with "PageMap asked for range which it does not have" during asynchronuous refreshing of grids. I catched some of sources of errors in the ExtJS 4.2.1 code and created simple override, that works for me. You can try if it will work for you. I will be happy for your feedback.

Ext.override(Ext.view.Table, {
    getRecord: function (node) {
        node = this.getNode(node);
        if (node) {
            var recordIndex = node.getAttribute('data-recordIndex');
            if (recordIndex) {
                recordIndex = parseInt(recordIndex, 10);
                if (recordIndex > -1) {
                    // Eliminates one of sources of "PageMap asked for range which it does not have" error
                    if (this.store.getCount() > 0) {
                        return this.store.data.getAt(recordIndex); 
                    }
                }
            }
            return this.dataSource.data.get(node.getAttribute('data-recordId'));
        }
    },
    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;
        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 (!isMetadataRecord) {
            itemClasses[0] = Ext.baseCSSPrefix + "grid-row";
            if (selModel && selModel.isRowSelected) {
                var storeRows = this.getStore().getCount();
                // Eliminates one of sources of "PageMap asked for range which it does not have" error
                if (rowIdx + 1 < storeRows) { 
                    if (selModel.isRowSelected(rowIdx + 1)) {
                        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);
        }
    }
});

all these codes don't work for me, after many debugging I wrote this override which solve the problem.



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


});

This is my solution for my specific case with the same error

it somehow lost DOM element for child this code fix that

Ext.define('override.Ext.view.Table', {
  /**
   * Returns the node given the passed Record, or index or node.
   * @param {HTMLElement/String/Number/Ext.data.Model} nodeInfo The node or record
   * @param {Boolean} [dataRow] `true` to return the data row (not the top level row if wrapped), `false`
   * to return the top level row.
   * @return {HTMLElement} The node or null if it wasn't found
   */
  override: 'Ext.view.Table',
  getNode: function (nodeInfo, dataRow) {
    // if (!dataRow) dataRow = false
    var fly,
      result = this.callParent(arguments)

    if (result && result.tagName) {
      if (dataRow) {
        if (!(fly = Ext.fly(result)).is(this.dataRowSelector)) {
          result = fly.down(this.dataRowSelector, true)
        }
      } else if (dataRow === false) {
        if (!(fly = Ext.fly(result)).is(this.itemSelector)) {
          result = fly.up(this.itemSelector, null, true)
        }
        if (this.xtype == 'gridview' && !this.body.dom.querySelector(`#${result.id}`)) {
          result = null
        }
      }
    }
    return result
  },
})
发布评论

评论列表(0)

  1. 暂无评论