简体   繁体   English

ExtJs-排序列后使用CellEditor的GridPanel中的错误

[英]ExtJs - Errors in GridPanel using CellEditor after sorting a column

Seen using ExtJs 5.1.0, Chrome 44.0+ 使用ExtJs 5.1.0,Chrome 44.0+可以看到

I'm having an intermittent issue where when using the CellEditor to modify the contents of a grid panel, errors are thrown when trying to edit cells after sorting one of the columns. 我遇到一个间歇性问题,当使用CellEditor修改网格面板的内容时,在对一列进行排序后尝试编辑单元格时会引发错误。

Here is the stack trace: 这是堆栈跟踪:

Uncaught TypeError: Cannot read property 'parentNode' of nullExt.define.onShow @ CellEditor.js?ver=911111541:147
Ext.define.show @ Component.js?ver=911111541:5104
Ext.define.startEdit @ Editor.js?ver=911111541:333
Ext.Base.Base.addMembers.callParent @ Base.js?ver=911111541:1255
Ext.define.startEdit @ CellEditor.js?ver=911111541:132
Ext.define.showEditor @ CellEditing.js?ver=911111541:536
Ext.define.startEdit @ CellEditing.js?ver=911111541:479
Ext.define.onCellClick @ Editing.js?ver=911111541:446
fire @ Event.js?ver=911111541:387
doFireEvent @ Observable.js?ver=911111541:654
prototype.doFireEvent @ EventDomain.js?ver=911111541:293
fireEventArgs @ Observable.js?ver=911111541:587
fireEvent @ Observable.js?ver=911111541:540
Ext.define.processItemEvent @ Table.js?ver=911111541:2445
Ext.define.processUIEvent @ View.js?ver=911111541:619
Ext.define.handleEvent @ View.js?ver=911111541:562
fire @ Event.js?ver=911111541:387
Ext.define.fire @ Dom.js?ver=911111541:367
Ext.define.publish @ Dom.js?ver=911111541:339
Ext.define.doDelegatedEvent @ Dom.js?ver=911111541:398
Ext.define.onDelegatedEvent @ Dom.js?ver=911111541:379
(anonymous function) @ Function.js?ver=911111541:145

The relevant bit of code in the CellEditor's onShow method: CellEditor的onShow方法中的相关代码位:

if (me.el.dom.parentNode !== me.renderTo) {
    me.renderTo.appendChild(me.el.dom);
}

The grid itself is empty to start with. 网格本身是空的。 It has a toolbar associated with it with buttons that allow you to add/duplicate/delete rows. 它具有与之相关的工具栏,其按钮使您可以添加/复制/删除行。

Here is a fiddle that represents this setup (unable to reproduce in the fiddle however): 这是代表此设置的小提琴(但是无法在小提琴中重现):

https://fiddle.sencha.com/#fiddle/top https://fiddle.sencha.com/#fiddle/top

The steps to reproduce are roughly as follows: 重现步骤大致如下:

In Chrome 44.0 (Not seen in other browsers)

1) Add a new row, fill in the fields
2) Sort on field2
3) Add three new rows
4) Add a value to one of the new rows under column for field 2
5) Sort on field2
6) Try to edit a cell in the field2 column

At this point, around 10% of the time, the error will show up and the grid will be broken. 此时,大约有10%的时间会出现错误,并且网格将被破坏。 If at step 6 the problem isn't reproduced, you can navigate to another tab in the browser, wait a couple minutes, go back to the grid and try to edit it, and the problem will happen. 如果在第6步未出现问题,则可以导航到浏览器中的另一个选项卡,等待几分钟,返回到网格并尝试对其进行编辑,然后问题就会发生。 This is near 100% reproduction rate. 这接近100%的复制率。

Note that the steps aren't exact. 请注意,步骤不正确。 You could, for example, try this using the first column instead. 例如,您可以尝试使用第一列来代替。 Or add some arbitrary number of rows. 或添加任意数量的行。 The longer you play with the grid and try sorting it, the higher the chance you'll see the error. 您玩网格并尝试对其进行排序的时间越长,看到错误的机会就越大。

If you see the error and then try to edit any cell in the grid again, you will get this error: 如果看到错误,然后尝试再次编辑网格中的任何单元格,则会收到此错误:

Uncaught TypeError: Cannot read property 'style' of nullExt.define.setSize @ CompositeElementLite.js?ver=911111541:1674
Ext.define.setSize @ Component.js?ver=911111541:4922
Ext.define.setWidth @ Component.js?ver=911111541:5033
Ext.define.realign @ CellEditor.js?ver=911111541:282
Ext.define.startEdit @ Editor.js?ver=911111541:334
Ext.Base.Base.addMembers.callParent @ Base.js?ver=911111541:1255
Ext.define.startEdit @ CellEditor.js?ver=911111541:132
Ext.define.showEditor @ CellEditing.js?ver=911111541:536
Ext.define.startEdit @ CellEditing.js?ver=911111541:479
Ext.define.onCellClick @ Editing.js?ver=911111541:446
fire @ Event.js?ver=911111541:387
doFireEvent @ Observable.js?ver=911111541:654
prototype.doFireEvent @ EventDomain.js?ver=911111541:293
fireEventArgs @ Observable.js?ver=911111541:587
fireEvent @ Observable.js?ver=911111541:540
Ext.define.processItemEvent @ Table.js?ver=911111541:2445
Ext.define.processUIEvent @ View.js?ver=911111541:619
Ext.define.handleEvent @ View.js?ver=911111541:562
fire @ Event.js?ver=911111541:387
Ext.define.fire @ Dom.js?ver=911111541:367
Ext.define.publish @ Dom.js?ver=911111541:339
Ext.define.doDelegatedEvent @ Dom.js?ver=911111541:398
Ext.define.onDelegatedEvent @ Dom.js?ver=911111541:379(anonymous function) @ Function.js?ver=911111541:145

Here's some of my code which may or may not be relevant: 这是我的一些可能不相关的代码:

In the initComponent function, I first create the cellediting plugin: 在initComponent函数中,我首先创建cellediting插件:

this._cellEditing = Ext.create('Ext.grid.plugin.CellEditing', {
  clicksToEdit: 1,
disabled: this.getDisableEdit()
});

This will be assigned to the plugin config item later for the grid itself: 稍后将为网格本身将其分配给插件配置项:

plugins: [
  this._cellEditing
]

Here's the add button's logic: 这是添加按钮的逻辑:

// Create a record instance through the ModelManager
var newRow = new BidPackageSchedulesGridPanel.Model();
this.getStore().add(newRow);
if (moveToRow) {
  this._cellEditing.startEdit(newRow, 1);
}

And the model itself: 和模型本身:

Ext.define('BidPackageSchedulesGridPanel.Model', {
  extend: "Ext.data.Model",
fields: [
    FieldIds.FIELD_1,
FieldIds.FIELD_2,
FieldIds.FIELD_3,
// Must specify a default value of "" in order to display null values correctly in IE.
{
      name: FieldIds.QUANTITY,
type: 'string',
defaultValue: ""
}

  ],
validators: {
    FIELD_1: [presenceValidator, 'length'],
FIELD_2: 'length',
FIELD_3: 'length',
QUANTITY: presenceValidator
  },
identifier: 'sequential'
});

And where the store is initialized in the config for the grid panel: 以及在网格面板的配置中初始化存储的位置:

store:  {
  model: Ext.create("BidPackageSchedulesGridPanel.Model"),
data: []
},

We use a data provider to load the store data. 我们使用数据提供程序来加载商店数据。

The columns for the first three fields are created using this logic: 使用以下逻辑创建前三个字段的列:

_createColumn: function(label, dataIndex) {
  var column = {
    text: Ext.String.htmlEncode(label),
dataIndex: dataIndex,
sortable: this.isJobSchedule(),
draggable: false,
flex: 1
};

if (this.isJobSchedule() || dataIndex == FieldIds.FIELD_3) {
    Ext.apply(column, {
      editor: {
        xtype: 'textfield'
}
    });
}
  return column;
},

Let me know if I can provide any additional code. 让我知道是否可以提供其他代码。 I suspect this is a bug in Ext, and I've filed a bug report with them, but a workaround would be sufficient for now if necessary. 我怀疑这是Ext中的错误,我已经向他们提交了错误报告,但是如果需要的话,现在可以采取解决方法。

Thanks! 谢谢!

I have fixed this issue, however, it may have unforeseen consequences. 我已经解决了这个问题,但是,它可能会带来无法预料的后果。 I noticed this comment in CellEditor.js, in the setGridMethod: 我在CellEditor.js的setGridMethod中注意到了此注释:

        // On view refresh, we need to copy our DOM into the detached body to prevent it from being garbage collected.
        view.on(viewListeners);

And indeed, I put a breakpoint in the GarbageCollector and saw that cell editor node was being garbage collected improperly. 确实,我在GarbageCollector中设置了一个断点,并看到未正确收集单元格编辑器节点。 I set the garbage collector interval (In GarbageCollector.js) to 10 seconds. 我将垃圾收集器间隔(在GarbageCollector.js中)设置为10秒。 After adding data to the grid and sorting, and the ten second window passing, the problem was reproducible 100% of the time. 在将数据添加到网格并进行排序,并经过十秒钟的窗口后,该问题在100%的时间中都是可重现的。 It was being garbage collected because its parent node was null (see the AND condition in Ext.isGarbage). 正在对其进行垃圾回收,因为其父节点为空(请参见Ext.isGarbage中的AND条件)。

In the CellEditor.onViewRefresh() function, for the component that was being garbage collected, this method was not giving the component a parent node, and then it was being garbage collected. 在CellEditor.onViewRefresh()函数中,对于正在垃圾回收的组件,此方法未给组件提供父节点,然后又对其进行垃圾回收。

I changed 我变了

    } else if (!sorting) {
        Ext.getDetachedBody().dom.appendChild(dom);
    }

to

    } else {
        Ext.getDetachedBody().dom.appendChild(dom);
    }

and the problem has gone away. 问题就消失了。 I've tested the grid editing functionality and nothing appears to be broken. 我已经测试了网格编辑功能,但似乎没有任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM