【问题标题】:Extjs create a grid feature or grid plugin that sets a tooltip for each column in the gridExtjs 创建一个网格功能或网格插件,为网格中的每一列设置一个工具提示
【发布时间】:2013-08-30 15:09:24
【问题描述】:

这个问题有添加工具提示的答案: Extjs4 set tooltip on each column hover in gridPanel

我对这个问题最受好评的答案有一个后续问题,即修改渲染器功能以添加如下工具提示:

{
    xtype : 'gridcolumn',
    dataIndex : 'status',
    text : 'Status',
    renderer : function(value, metadata) {
                    metadata.tdAttr = 'data-qtip="' + value + '"';
                    return value;
                }
}

我想要一个使用上述实现设置自定义工具提示的网格插件或功能。

问题是我怎样才能添加我的东西,但同时又不带走用于特定网格的用户定义渲染器函数。本质上,我想为所有网格添加工具提示功能,但不会取消为某些网格上的某些列指定自定义渲染器的能力。

我想可能的替代方案是另一个侵入性较小的地方,我可以修改这个 metadata.tdAttr 值。也许有人会知道的事件?

【问题讨论】:

    标签: extjs plugins extjs4 tooltip sencha-architect


    【解决方案1】:

    在您的插件init 方法中,您将能够遍历网格的列(此时网格的构造函数和initComponent 方法已经被调用)。

    这意味着您可以检查每一列以查看用户是否设置了自定义渲染器。如果没有,你可以放一个,如果有,你可以把现有的渲染器和你的链接起来。

    编辑

    Ext.define('My.Plugin', {
    
        init: function(grid) {
    
            // You may not need the scope, but if you do, this binding will
            // allow to preserve the scope configured in the column...
            var pluginRenderer = Ext.Function.bind(this.renderer, this);
    
            Ext.each(grid.query('gridcolumn'), function(col) {
                var renderer = col.renderer;
                col.renderer = renderer
                    ? Ext.Function.createSequence(renderer, pluginRenderer)
                    : pluginRenderer;
            });
        }
    
        ,renderer: function(value, md) {
    
            // ...
    
            // You must return, in case your renderer is the only one (if
            // there is another one, this return will be ignored by createSequence)
            return value;
        }
    });
    

    【讨论】:

    • 它的链接部分我不确定......你能给出一些代码如何做到这一点。
    • 我添加了一个插件示例代码,并注释了一些你需要避免的陷阱。
    • 非常感谢... rixo.. createSequence 是迄今为止我不知道的灵丹妙药.. 现在我知道了,我可以想到很多地方在尝试扩展功能而不是纯粹覆盖时使用它。
    • 将插件类的上下文传递给函数的加分项......很容易错过,调试起来很心痛
    【解决方案2】:

    我接受了下一个合乎逻辑的结论:

    并将其制成基于plugin 的完整可配置解决方案,只需要很少的配置即可使用。和 Sencha Architect 配合得很好。

    动机

    研究这个并让它工作的主要动机是DateColumn 具有标记为hiddenrenderer 配置参数,因此Sencha Architect 不允许您在Config 面板中修改它.我明白为什么,它驱使我找到这个解决方案,我认为这是正确的,从长远来看是最可维护和可重用的。

    撰写本文时:

    我正在使用 Sencha Architect 3.x 和 ExtJS 4.2.2,这些说明包括如何在该环境中应用这些功能。如果您不使用 Sencha Architect,您只需要自己创建和管理文件。 我发现在处理任何大小的 ExtJS 项目时都非常高效。

    首先是实际的GridPlugin

    JSResource添加到您的项目中,将url设置为js/CellToolTip.js,然后复制以下代码作为其内容。

    js/CellToolTip.js

    Ext.define('Ext.grid.plugin.CellToolTip', {
        extend: 'Ext.AbstractPlugin',
        alias: 'plugin.CellQTip',
        config: {
            debug: false
        },
    
        init: function(grid) {
    
            // You may not need the scope, but if you do, this binding will
            // allow to preserve the scope configured in the column...
            var pluginRenderer = Ext.Function.bind(this.renderer, this);
    
            Ext.each(grid.query('gridcolumn'), function(col) {
                var renderer = col.renderer;
                col.renderer = renderer ? Ext.Function.createSequence(renderer, pluginRenderer) : pluginRenderer;
            });
        },
    
        renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
            var col = view.getGridColumns()[colIndex];
            var fn = this[col.itemId];
            if (fn) {
                metaData.tdAttr = fn(value, metaData, record, rowIndex, colIndex, store, view);
            }     
            return value;
        }
    });
    

    以下是将其应用于GridPanel 的方法:

    您将所谓的Process Config 函数添加到要应用插件的每个GridPanel

    它的作用是充当拦截器函数,并允许您在实际应用之前修改Componentconfig

    processBlobInfoGridPanel: function(config) {
        var ttp = Ext.create('Ext.grid.plugin.CellToolTip', {
            createdOn: function(value, metaData, record, rowIndex, colIndex, store, view) { return 'data-qtip="' + value.toUTCString() + '"'; },
            byteSize: function(value, metaData, record, rowIndex, colIndex, store, view) { return 'data-qtip="' + value + ' bytes"'; }
        });
        config.plugins = [ttp];
        return config;
    },
    

    如何将这些添加到 Sencha Architect 项目中:

    首先,这会创建具有自己配置的plugin,其中每个属性是您要应用插件的每个ColumnitemId

    与每个Column 关联的函数与renderer 配置具有完全相同的签名。

    这里的函数实现很短,而且只有一行。这只是一个例子,为了简洁起见。

    工具提示功能说明:

    createdOnColumn 中为每个Cell 添加一个ToolTip 作为UTC 中的时间。

    byteSizeColumn 中为每个 Cell 添加一个 ToolTip,以详细显示原始字节数。

    然后将配置插件的实例添加到GridPanelconfig,并返回config的实例。

    奖励课程

    在 Sencha Architect 中,我创建了一个 Column 来表示 ResourcesSize,我想将字节大小显示为具有最大适当间隔的人类可读格式。所以我添加了一个renderer 函数来执行此操作。

    我意识到我将在多个 GridPanel 实例上需要这个 Column,因此将它提升为一个类

    执行此操作的方法是右键单击Column 并选择Promote to Class。 Sencha Architect 然后创建以下代码并将其放入您的app/view 目录中的文件中,该文件的名称与您在Config 面板中指定的userClassName 相同。

    Ext.define('AdminApp.view.ByteSize', {
        extend: 'Ext.grid.column.Column',
        alias: 'widget.byteSize',
    
        itemId: 'byteSize',
        dataIndex: 'size',
        text: 'Size',
        tooltip: 'Byte size in human readable format',
    
        initComponent: function() {
            var me = this;
    
            me.callParent(arguments);
        },
    
        renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
            // convert bytes into a human readable format"
            var bytes = value;
            if      (bytes>=1073741824) {bytes=(bytes/1073741824).toFixed(2)+' GB';}
            else if (bytes>=1048576)    {bytes=(bytes/1048576).toFixed(2)+' MB';}
            else if (bytes>=1024)       {bytes=(bytes/1024).toFixed(2)+' KB';}
            else if (bytes>1)           {bytes=bytes+' bytes';}
            else if (bytes==1)          {bytes=bytes+' byte';}
            else                        {bytes='0 byte';}
            return bytes;
        }
    
    });
    

    现在这个Column 的原始实例指向这个新的Class

    columns: [
        {
            xtype: 'byteSize',
            itemId: 'byteSize'
        }
    ]
    

    现在要在 Sencha Architect 的其他 GridPanel 实例中使用它,只需右键单击链接到这个新类的 Column 实例并选择 Duplicate。然后将复制的实例拖到您要使用ByteSize 类的GridPanel 并将其放入Columns 的列表中。然后独立配置每个克隆实例。

    ByteClass 的默认值或行为的任何更改都会自动影响所有实例。

    路线图

    这是第一个可行的最小可行解决方案,可以进行明显的改进。例如,如果已经有内容,我想修复它附加到metaData.tdAttr 的位置,而不是盲目地覆盖那里的内容。

    将对此Gist on GitHub进行任何改进。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多