简体   繁体   中英

Sencha 6.5 (modern) how to dynamically change the items in a menu in a title bar?

Well considering a grid I create in my application:

    {
        xtype: 'ordergrid',
        itemId: 'ordergrid',

        titleBar: {
            shadow: false,
            items: [{
                align: 'right',
                xtype: 'button',
                text: 'Update status',
                stretchMenu: true,
                menu: {
                    itemId: 'status_menu',
                    defaults: {
                        handler: 'updateStatus'
                    },
                    indented: false,
                    items: [{
                        text: 'test1',
                        value: 'test1'
                    }, {
                        text: 'test2',
                        value: 'test2'
                    }, {
                        text: 'test3',
                        value: 'test4'
                    }]
                }
            }]
        },

With ordergrid being defined with:

extend: 'Ext.grid.Grid',
xtype: 'ordergrid',

I wish to modify the items of the menu dynamically. I've first tried doing this through a store:

                menu: {
                    itemId: 'status_menu',
                    defaults: {
                        handler: 'updateStatus'
                    },
                    indented: false,
                    store: { type: 'status' }

Though this doesn't seem to work. Then I tried accessing this menu through a component query, during the init function of some controller:

Ext.define('BinkPortalFrontend.view.main.OrderController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.order',

    init: function () {
        console.log('..... initializing ......');
        const menus = Ext.ComponentQuery.query('ordergrid #status_menu');
        const menu = menus[0];
        menu.setItems([{
            text: 'some',
            value: 'some'
        }, {
            text: 'new',
            value: 'mew'
        }]);
    },
};

However this returns an error: "Cannot read property 'setItems' of undefined" Debugging shows the obvious problem: it doesn't find any menu.

What's more, even a "catch all" query like

Ext.ComponentQuery.query('menu');

or

Ext.ComponentQuery.query('#status_menu');

Shows an empty array: so what's going on? (I most definitely see the menu from its initial load).

There is one reason your menu is not created. Menu will created whenever button will tap or whenever getMenu() method get called.

If you want to get your menu using Ext.ComponentQuery.query() , so for this you need to do use initialize event of button and forcefully create menu using getMenu() method like below :-

{
    xtype: 'button',
    text: 'Update status',
    stretchMenu: true,
    menu: {
        itemId: 'status_menu',
        indented: false,
        items: [{
            text: 'test1',
            value: 'test1'
        }, {
            text: 'test2',
            value: 'test2'
        }, {
            text: 'test3',
            value: 'test4'
        }]
    },
    listeners: {
        initialize: function(btn) {
            Ext.defer(function() {
                // This will print undefined because menu have not created  
                console.log(Ext.ComponentQuery.query('#status_menu')[0]);

                //When we use getMenu method it will create menu item  
                btn.getMenu().hide();

                // This will print menu component  
                console.log(Ext.ComponentQuery.query('#status_menu')[0]);
            }, 10)
        }
    }
}

Another way you can use getMenu() method of button . It will return the menu component.

In this FIDDLE , I have created a demo using grid , button and menu . I hope this will help/guide you to achieve your requirement.

CODE SNIPPET

Ext.application({
    name: 'Fiddle',

    launch: function () {
        var store = Ext.create('Ext.data.Store', {
            fields: ['name', 'email', 'phone'],
            data: [{
                'name': 'Lisa',
                "email": "lisa@simpsons.com",
                "phone": "555-111-1224"
            }, {
                'name': 'Bart',
                "email": "bart@simpsons.com",
                "phone": "555-222-1234"
            }, {
                'name': 'Homer',
                "email": "home@simpsons.com",
                "phone": "555-222-1244"
            }, {
                'name': 'Marge',
                "email": "marge@simpsons.com",
                "phone": "555-222-1254"
            }]
        });

        Ext.create('Ext.grid.Grid', {
            title: 'Change menu items dynamically',
            titleBar: {
                shadow: false,
                items: [{
                    align: 'right',
                    xtype: 'button',
                    text: 'Update status',
                    stretchMenu: true,
                    itemId: 'statusbtn',
                    menu: {
                        itemId: 'status_menu',
                        defaults: {
                            // handler: 'updateStatus'
                        },
                        indented: false,
                        items: [{
                            text: 'test1',
                            value: 'test1'
                        }, {
                            text: 'test2',
                            value: 'test2'
                        }, {
                            text: 'test3',
                            value: 'test4'
                        }]
                    },
                    listeners: {
                        initialize: function (btn) {
                            Ext.defer(function () {
                                // This will undefined because menu has not been created
                                console.log(Ext.ComponentQuery.query('#status_menu')[0]);

                                //When we use getMenu method it will create menu item
                                btn.getMenu().hide();

                                // This will menu component
                                console.log(Ext.ComponentQuery.query('#status_menu')[0]);
                            }, 10)
                        }
                    }
                }, {
                    xtype: 'button',
                    align: 'right',
                    text: 'Change Items',
                    handler: function (btn) {
                        var newItems = [];

                        store.each(rec => {
                            newItems.push({
                                text: rec.get('name'),
                                value: rec.get('name')
                            })
                        });
                        /*
                         *  You can also get menu using button
                         *  btn.up('titlebar').down('#statusbtn').getMenu().setItems(newItems);
                         */
                        Ext.ComponentQuery.query('#status_menu')[0].setItems(newItems);
                        Ext.toast('Menu items has been change. Please check', 2000);
                    }
                }]
            },
            store: store,
            columns: [{
                text: 'Name',
                dataIndex: 'name',
                width: 200
            }, {
                text: 'Email',
                dataIndex: 'email',
                width: 250
            }, {
                text: 'Phone',
                dataIndex: 'phone',
                width: 120
            }],
            height: 200,
            layout: 'fit',
            fullscreen: true
        });
    }
});

For more details about component you can also see this ComponentManager

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM