ExtJS 6:在单个网格列中使用多个编辑器的问题

8

注释

ExtJS版本:6.2.1.167

Fiddle: fiddle.sencha.com/#view/editor&fiddle/1tlt

这个功能在ExtJS 2.x中可用,没有任何问题。


目标

创建一个带有分组功能和单元格编辑插件的网格,可以在单个列中使用多个不同的编辑器(textfieldcombo)。

该网格已经颠倒了传统的表格系统,使字段名称和记录值垂直显示。下面是表头的示例:

+-------------+-----------------+-----------------+-----------------
- Field Names - Record 1 Values - Record 2 Values - Editable Column
+-------------+-----------------+-----------------+-----------------

因为有数百个字段,但只有几条记录可供比较,因此我们无法使用传统系统。


代码

这里是fiddle

以下是主要的代码,它允许我使用多个编辑器:

Ext.define('MemberCellEditing', {

  extend: 'Ext.grid.plugin.CellEditing',
  xtype: 'membercellediting',
  alias: 'plugin.membercellediting',

  getCachedEditor: function(editorId, record, column) {
    var me = this,
      editors = me.editors,
      dropDownName = record.get('dropDown');

    // If dropdown field, use dropdown name as editor id
    if (dropDownName && dropDownName != 'N') editorId = dropDownName;

    // Attempt to get editor
    var editor = editors.getByKey(editorId);

    if (!editor) {

      if (dropDownName && dropDownName != 'N') {
        // Retrieve combo
        var combo = DropDownManager.getCombo(editorId);

        // Create editor with combo
        editor = Ext.create('Ext.grid.CellEditor', {
          editorId: editorId, // Each dropdown field will have its own combo
          field: combo,
          floating: true
        });
      } else {
        // Use default editor configured for column
        editor = column.getEditor(record);
      }

      if (!editor) {
        return false;
      }

      // Allow them to specify a CellEditor in the Column
      if (!(editor instanceof Ext.grid.CellEditor)) {
        // Apply the field's editorCfg to the CellEditor config.
        // See Editor#createColumnField. A Column's editor config may
        // be used to specify the CellEditor config if it contains a field property.
        editor = new Ext.grid.CellEditor(Ext.apply({
          floating: true,
          editorId: editorId,
          field: editor
        }, editor.editorCfg));
      }

      // Add the Editor as a floating child of the grid
      // Prevent this field from being included in an Ext.form.Basic
      // collection, if the grid happens to be used inside a form
      editor.field.excludeForm = true;

      // If the editor is new to this grid, then add it to the grid, and ensure it tells us about its life cycle.
      if (editor.column !== column) {
        editor.column = column;
        column.on('removed', me.onColumnRemoved, me);
      }
      editors.add(editor);
    }

    // Inject an upward link to its owning grid even though it is not an added child.
    editor.ownerCmp = me.grid.ownerGrid;

    if (column.isTreeColumn) {
      editor.isForTree = column.isTreeColumn;
      editor.addCls(Ext.baseCSSPrefix + 'tree-cell-editor');
    }

    // Set the owning grid.
    // This needs to be kept up to date because in a Lockable assembly, an editor
    // needs to swap sides if the column is moved across.
    editor.setGrid(me.grid);

    // Keep upward pointer correct for each use - editors are shared between locking sides
    editor.editingPlugin = me;
    return editor;
  }
});

问题

我的代码可以让你在单个列中使用多个编辑器,但它会“随机”抛出错误。我说“随机”,是因为我无法找到错误的实际原因。

错误#1 无法获取未定义或空引用的style属性

截图

enter image description here

错误#2 无法获取未定义或空引用的parentNode属性

截图

enter image description here

这两个错误的原因是当前引用的编辑器上的el属性已被销毁,意味着没有dom属性。

如何重现

这是我无法解决此问题的部分原因。我无法找到一个具体的方法来复制该问题。不幸的是,我可以获得错误的方式是点击/切换到单元格,输入数据,切换到其他单元格,切换组等的随机组合... 我目前通常使用的方法涉及输入一些随机数据,然后疯狂地点击以在两个相邻单元格之间交替聚焦。大多数时候,少于30秒就会出现错误。

我目前的理论是有一个事件被触发,调用某个函数,由于某种原因销毁了编辑器的el属性。我尝试查看错误调用堆栈顶部的值,似乎在该点上el属性已经被销毁。

底线

我正在寻找如何跟踪问题实际原因的建议。

更新

事实证明,目前存在一个与在单元格编辑器中使用组合框有关的错误。这里有另一个人遇到的非常类似的问题:

https://www.sencha.com/forum/showthread.php?330959-ExtJs-6-2-CellEditing-plugin-editor-el-dom-is-null

这里是错误ID:EXTJS-23330

据Sencha Support表示,目前没有可用的解决方法,该bug仍然存在。

更新 #2

该缺陷存在于 6.0.2 和 6.5 版本。

幸运的是,我找到了一种更加一致地重现该缺陷的方法:

  1. 将光标悬停在 Group A 上 5 秒钟。 展开 Group A。
  2. 将光标悬停在 (Field 1, Value Column) 上 5 秒钟。
  3. 单击 (Field 1, Value Column)。
  4. 等待 5 秒钟,然后折叠 Group A。
  5. 等待 3 秒钟,然后将光标悬停在 Group B 标题上。
  6. 等待 10 秒钟,然后将光标悬停在 Group A 标题上。
  7. 等待 3 秒钟,然后展开 Group A。
  8. 将光标悬停在 (Field 1, Value Column) 字段上 3 秒钟。
  9. 将光标悬停在 (Field 1, Value 2 Column) 上 3 秒钟。
  10. 单击 (Field 1, Value 2 Column)。

如果错误没有发生(似乎还未在6.5中发生):

  1. 等待 3 秒钟,然后单击 (Field 1, Value Column)。
  2. 等待 1 秒钟,然后再次单击 (Field 1, Value Column)。

它并不是100%可靠的,但比随机点击要可靠得多。


嗨 - 你最终对此做了什么?我在6.6.0中测试过,但无法重现。顺便说一句,我知道这已经过了很长时间了... - boggy
2个回答

0

它很容易使用,您只需要覆盖编辑器类并根据您的用例放置编辑器。请参考我的fiddle [https://fiddle.sencha.com/#fiddle/3jud&view/editor][1]


0

若没有更多的代码和调用堆栈信息,很难确定问题,但如果上述错误#2仍然是当前问题的良好示例,您应该能够将!editor.rendered检查的else更改为else if (!editor.destroyed),就像截图中断点上面显示的那样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接