3

这个问题有添加工具提示的答案: 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 值。也许有人会知道的事件?

4

2 回答 2

3

在您的插件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;
    }
});
于 2013-08-30T15:46:39.597 回答
2

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

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

动机

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

在撰写本文时:

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

首先是实际的GridPlugin

将 a 添加JSResource到您的项目中,将其设置urljs/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;
    }
});

这是您如何将其应用于 a 的方法GridPanel

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

它的作用是充当拦截器功能,并允许您在实际应用之前对其进行config修改Component

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使用自己的配置创建 ,其中每个属性都是您要应用插件itemId的每个属性。Column

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

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

工具提示功能说明:

createdOnToolTip为其中的每个添加一个Cell作为Column时间UTC

byteSizeToolTip为每个添加一个将原始字节CellColumn显示为详细信息的内容。

然后它将已配置插件的实例添加到configGridPanel并返回 的实例config

奖金班

在 Sencha Architect 中,我创建了一个Column来表示Sizeof Resources,我想将字节大小显示为具有最大适当间隔的人类可读格式。所以我添加了一个renderer函数来做到这一点。

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

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

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

});

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

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

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

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

路线图

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

在 GitHub 上对此 Gist 进行任何增强。

于 2013-12-03T03:36:14.707 回答