使用 Ext.grid.Panel.reconfigure() 打破了网格 RowEditing 插件

Posted

技术标签:

【中文标题】使用 Ext.grid.Panel.reconfigure() 打破了网格 RowEditing 插件【英文标题】:Using Ext.grid.Panel.reconfigure() breaks the grids RowEditing plugin 【发布时间】:2012-08-15 03:49:04 【问题描述】:

我正在创建一个 extjs 网格面板,其中包含一组用户可配置的列。 Ext.grid.Panel 组件为此提供了一个方便的 reconfigure(store, columns) 方法。

此方法按预期工作,可以重新配置网格的存储/列,而无需完全销毁和重新创建网格。但是,如果您使用 Ext.grid.plugins.RowEditing 插件提供内联行编辑,则在使用新列重新配置网格后,列会不同步。

这尤其令人沮丧,因为 RowEditing 插件已经监视添加/删除/调整列大小并正确处理这些。我怀疑这只是当前 ExtJs 4.1 版本中的一个疏忽。

我想要的是 RowEditor 在使用新列重新配置网格时更新其编辑器列表和宽度,而不破坏/重新创建网格/视图。

经过多次谷歌搜索,似乎我并不是唯一一个在寻找具有内联编辑支持的可轻松重新配置的列列表的人。

【问题讨论】:

【参考方案1】:

Ext.grid.Panel 提供了一个“重新配置”事件,在任何时候调用 reconfigure() 方法后都会触发该事件。但是,在当前 4.1 版本的 ExtJs 中,RowEditing 插件不会挂钩此事件!

看来我们需要自己做繁重的工作。最终的解决方案相当简单,虽然花了几个小时才得出最终的代码。

RowEditing 插件创建了 RowEditor 组件的一个实例(明白了吗?记住这两个是分开的,名称相似但组件不同!)。 RowEditing 插件与网格相关联,它与必要的事件挂钩,以了解何时显示行编辑器等。RowEditor 是在行上弹出以在网格中进行内联编辑的可视化组件。

起初我尝试了十几种不同的方式重新配置行编辑器。我尝试调用内部方法、init 方法、resize 方法等……然后我注意到架构的一些优点。有一个对 RowEditor 实例的内部引用,其中包含获取行编辑器和延迟加载(如果需要)的方法。那是关键!

您可以在不销毁 RowEditing 插件的情况下销毁 RowEditor(您不能动态加载/卸载插件),然后重新创建 RowEditor。

还有一个问题,即 Ext 网格的编辑插件为 getEditor()setEditor() 的每一列添加了一些扩展方法,用于获取/设置每一列的正确编辑器类型。当您重新配置网格时,任何应用的扩展方法都“消失”(您有一些从未应用过这些方法的新列)。因此,您还需要通过在插件上调用 initFieldAccessors() 方法来重新应用这些访问器方法。

这是我的网格面板重新配置事件的处理程序:

/**
* @event reconfigure
* Fires after a reconfigure.
* @param Ext.grid.Panel this
* @param Ext.data.Store store The store that was passed to the @link #method-reconfigure method
* @param Object[] columns The column configs that were passed to the @link #method-reconfigure method
*/
onReconfigure: function (grid, store, columnConfigs) 
    var columns = grid.headerCt.getGridColumns(),
        rowEditingPlugin = grid.getPlugin('rowEditor');

    //
    // Re-attached the 'getField' and 'setField' extension methods to each column
    //
    rowEditingPlugin.initFieldAccessors(columns);

    //
    // Re-create the actual editor (the UI component within the 'RowEditing' plugin itself)
    //
    // 1. Destroy and make sure we aren't holding a reference to it.
    //
    Ext.destroy(rowEditingPlugin.editor);
    rowEditingPlugin.editor = null;
    //
    // 2. This method has some lazy load logic built into it and will initialize a new row editor.
    //
    rowEditingPlugin.getEditor();

我使用配置侦听器将它附加到我的网格面板中:

listeners: 
    'reconfigure': Ext.bind(this.onReconfigure, this)

【讨论】:

什么是“我”?我想你在某个地方有me = this @AramKocharyan 是的,对不起,在我的许多例程开始时,我使用var me = this; 行来消除this 的含义,尤其是在闭包中。这条线特别糟糕,因为我同时使用了我和这个!我将编辑答案以仅使用 this 来撰写这篇文章。 谢谢!这也是我尝试过的,但由于我在与listeners 相同的对象中定义onReconfigure,所以在那个阶段它不可用。这两个属性是否位于不同的位置,例如子类? @AramKocharyan 都在一个文件中。它应该工作得很好。我怀疑这与您应用监听器的方式/时间有关(这是您提到的时间部分)。我在initComponent 中应用了监听器,这意味着整个类已经被定义并且可以使用了。如果您需要帮助,请在您的源代码中发布一个新的 *** 问题,我会看看。【参考方案2】:

似乎这个问题已经在最新的 ExtJS 版本中得到纠正 - 版本 4.1.1a 至少集成了类似于 Ben Swayne 实现的功能。

【讨论】:

以上是关于使用 Ext.grid.Panel.reconfigure() 打破了网格 RowEditing 插件的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)