在列标题下拉菜单中添加自定义按钮{EXTJS 4}

时间:2012-04-27 09:58:13

标签: extjs4

我想在extjs 4中的网格列标题下拉菜单中有一个按钮。 这样我就可以添加或删除数据库中链接的列。 The button in red area is the one i'm looking for...

任何帮助将不胜感激...... 谢谢.. :))

4 个答案:

答案 0 :(得分:14)

几个月前,我遇到了同样的问题。我设法通过扩展Ext.grid.header.Container(我已经超越getMenuItems方法)解决了这个问题。然而,最近,我发现了另一种需要较少编码的解决方案:只需在创建网格小部件后手动添加菜单项。

我会在这里发布第二个解决方案:

Ext.create('Ext.grid.Panel', {
    // ...
    listeners: {
        afterrender: function() {
            var menu = this.headerCt.getMenu();
            menu.add([{
                text: 'Custom Item',
                handler: function() {
                    var columnDataIndex = menu.activeHeader.dataIndex;
                    alert('custom item for column "'+columnDataIndex+'" was pressed');
                }
            }]);           
        }
    }
});

这是demo

更新

这是ExtJs4.1的demo

答案 1 :(得分:9)

从我所看到的情况来看,你应该避免后来的事件。

背景:

我正在构建的应用程序使用具有动态模型的商店。我希望我的网格有一个可从服务器获取的可自定义模型(所以我可以为我的可自定义网格提供可自定义的列)。

由于标题不可修改(因为商店被重新加载并破坏我修改的现有菜单 - 使用上面的示例)。具有相同效果的替代解决方案可以这样执行:

Ext.create('Ext.grid.Panel', {
    // ...

    initComponent: function () {
        // renders the header and header menu
        this.callParent(arguments);

        // now you have access to the header - set an event on the header itself
        this.headerCt.on('menucreate', function (cmp, menu, eOpts) {
            this.createHeaderMenu(menu);
        }, this);
    },

    createHeaderMenu: function (menu) {
        menu.removeAll();

        menu.add([
            // { custom item here }
            // { custom item here }
            // { custom item here }
            // { custom item here }
        ]);
    }
});

答案 2 :(得分:4)

对于那些希望不仅拥有一个“标准”列菜单但像我一样具有单独列式的用户,可以使用以下内容

initComponent: function ()
{
    // renders the header and header menu
    this.callParent(arguments);

    // now you have access to the header - set an event on the header itself
    this.headerCt.on('menucreate', function (cmp, menu, eOpts) {
        menu.on('beforeshow', this.showHeaderMenu);
    }, this);
},

showHeaderMenu: function (menu, eOpts)
{
    //define array to store added compoents in
    if(this.myAddedComponents === undefined)
    {
        this.myAddedComponents = new Array();
    }

    var columnDataIndex = menu.activeHeader.dataIndex,
        customMenuComponents = this.myAddedComponents.length;

    //remove components if any added
    if(customMenuComponents > 0)
    {
        for(var i = 0; i < customMenuComponents; i++)
        {
            menu.remove(this.myAddedComponents[i][0].getItemId());
        }

        this.myAddedComponents.splice(0, customMenuComponents);
    }

    //add components by column index
    switch(columnDataIndex)
    {
        case 'xyz': this.myAddedComponents.push(menu.add([{
                            text: 'Custom Item'}]));

                break;
    }
}

答案 3 :(得分:2)

我把@nobbler的回答用于创建一个插件:

Ext.define('Ext.grid.CustomGridColumnMenu', {
    extend: 'Ext.AbstractPlugin',
    init: function (component) {
        var me = this;

        me.customMenuItemsCache = [];

        component.headerCt.on('menucreate', function (cmp, menu) {
            menu.on('beforeshow', me.showHeaderMenu, me);
        }, me);
    },

    showHeaderMenu: function (menu) {
        var me = this;

        me.removeCustomMenuItems(menu);
        me.addCustomMenuitems(menu);
    },

    removeCustomMenuItems: function (menu) {
        var me = this,
            menuItem;

        while (menuItem = me.customMenuItemsCache.pop()) {
            menu.remove(menuItem.getItemId(), false);
        }
    },

    addCustomMenuitems: function (menu) {
        var me = this,
            renderedItems;

        var menuItems = menu.activeHeader.customMenu || [];

        if (menuItems.length > 0) {
            if (menu.activeHeader.renderedCustomMenuItems === undefined) {
                renderedItems = menu.add(menuItems);
                menu.activeHeader.renderedCustomMenuItems = renderedItems;
            } else {
                renderedItems = menu.activeHeader.renderedCustomMenuItems;
                menu.add(renderedItems);
            }
            Ext.each(renderedItems, function (renderedMenuItem) {
                me.customMenuItemsCache.push(renderedMenuItem);
            });
        }
    }
});

这是您使用它的方式(列配置中的customMenu允许您定义菜单):

Ext.define('MyGrid', {
    extend: 'Ext.grid.Panel',
    plugins: ['Ext.grid.CustomGridColumnMenu'],
    columns: [
        {
            dataIndex: 'name',
            customMenu: [
                {
                    text: 'My menu item',
                    menu: [
                        {
                            text: 'My submenu item'
                        }
                    ]
                }
            ]
        }
    ]
});

此插件的工作方式也解决了其他实现遇到的问题。由于自定义菜单项仅为每列创建一次(缓存已经渲染的版本),因此不会忘记是否先检查过它。