排除“PageMap要求的范围不存在”异常

7vhp5slm  于 2022-09-26  发布在  其他
关注(0)|答案(4)|浏览(209)

有时我会从Ext Js 4.2.1无限滚动网格中得到异常“PageMap asked for range which it does not have”。它在data/PageMap中引发。当然,不应该要求不存在的条目,但有时这是由框架本身完成的。似乎与添加/删除记录或重新加载网格有关。Sencha论坛中已经有一些关于这个主题的帖子,例如这个,但还没有提出致命的解决方案或错误修复。
同时,我必须避免让用户看到这个例外。这样做的好方法是什么?有趣的是,它有时只是由用户移动滚动条引起的,所以没有直接涉及到我的代码中的任何一行。

cotxawn7

cotxawn71#

我发现根本原因是,当它呈现行时,它确定它是否位于选定行之前。如果它正在处理最后一行,它仍然会查找第+1行。(外部视图。表:4.2.1中的931)
我的简单解决方案就是让它返回false:

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

wnvonmuf2#

克里斯托夫,
在异步刷新网格期间,我遇到了类似的问题:“PageMap要求提供它没有的范围”。我在ExtJS 4.2.1代码中找到了一些错误源,并创建了简单的覆盖,这对我来说很有用。如果它对你有用,你可以试试。我很高兴收到你的反馈。

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

ncecgwcz3#

所有这些代码对我都不起作用,经过多次调试后,我编写了这个重写来解决这个问题。

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

});
tf7tbtn2

tf7tbtn24#

这是我针对具有相同错误的特定案例的解决方案
它不知何故丢失了子级的DOM元素此代码修复了

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
  },
})

相关问题