ExtJS:class 范围内的问题

ExtJS: Issue with scope in class

我一直面临选择具有范围的确切组件的问题。正如您将在下面注意到的,我在 gridpanel 中创建了 2 个不同的函数。其中之一为 confirm 创建了 Ext.MessageBox。其他函数创建 Ext.window.Window 取决于 button 单击 MessageBox

这里的事情是;它应该 destroycomponentcancelno 按钮相关联。由于 var me = this 状态,两个按钮总是指向 gridpanel 并破坏 gridpanel 本身。

如何将 destroy 方法直接指向相关的 component

Ext.define('MyApp.FooGrid', {
    extend: 'Ext.grid.Panel',

    reference: 'fooGrid',

    getGridMenu: function () {
    // Here is the 'Update' function; with right-click user being able to see `contextmenu`
        var me = this;

        var ret = [
            {
                text: 'Update',
                listeners: {
                    click: me.onUpdate,
                    scope: me
                }
            }
        ];

        return me.callParent().concat(ret);
    },

    onUpdate: function () {
        var me = this,
            gridRec = this.getSelectionModel().getSelection(); // Here being able to retrieve row data.

        Ext.MessageBox.confirm(translations.confirm, translations.confirmChange, me.change, me);

        return gridRec;
    },

    change: function (button) {
        var me = this;
        var selectedRec = me.onUpdate();
        var selectedRecEmail = selectedRec[0].data.email; //Retrieves selected record's email with right-click action           

        if (button === "yes") {
            return new Ext.window.Window({
                alias: 'updateWin',
                autoShow: true,
                title: translations.update,
                modal: true,
                width: 350,
                height: 200,
                items: [
                    {
                        xtype: 'container',
                        height: 10
                    },
                    {
                        xtype: 'textfield',
                        width: 300,
                        readOnly: true,
                        value: selectedRecEmail //Display selected record email
                    },
                    {
                        xtype: 'textfield',
                        width: 300,
                        fieldLabel: translations.newPassword
                    }
                ],
                dockedItems: [
                    {
                        xtype: 'toolbar',
                        dock: 'bottom',
                        items: [
                            {
                                xtype: 'tbfill'
                            },
                            {
                                xtype: 'button',
                                text: translations.cancel,
                                listeners: {
                                    click: function () {
                                        me.destroy(); // Here is the bug: When user clicks on this button; should destroy current window but it destroys 'gridpanel' itself
                                    }
                                }
                            },
                            {
                                xtype: 'button',
                                text: translations.save,
                                listeners: {
                                    click: function () {
                                        console.log("I'll save you!");
                                    }
                                }
                            }
                        ]
                    }
                ]
            });
        } else {
            console.log('this is no!');
            me.destroy(); // Another bug raises through here: If user will click on No then 'messagebox' should destroy. This one is destroys the gridpanel as well.
        }
    }
});

How can I point destroy method directly to related component?

首先在确认框按钮的(No)点击,你不需要破坏它会在你点击进入No时自动隐藏框。

对于更新 window 而不是使用 me.destroy() 你需要直接使用 button.up('window').destroy() 所以它只会破坏你的更新 window 而不是 grid .

而且你不需要在 change 函数中再次调用 me.onUpdate() 否则它会再次显示确认框。您可以像这样 me.getSelection().

直接在 change 函数上获取选定的记录

在这个 Fiddle 中,我使用您的代码创建了一个演示,我已经努力得到结果。

代码片段

Ext.application({
    name: 'Fiddle',

    launch: function () {
        Ext.create('Ext.data.Store', {
            storeId: 'demostore',
            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: 'homer@simpsons.com',
                phone: '555-222-1244'
            }, {
                name: 'Marge',
                email: 'marge@simpsons.com',
                phone: '555-222-1254'
            }]
        });

        Ext.create('Ext.grid.Panel', {
            title: 'Demo GRID',
            store: 'demostore',
            columns: [{
                text: 'Name',
                dataIndex: 'name'
            }, {
                text: 'Email',
                dataIndex: 'email',
                flex: 1
            }, {
                text: 'Phone',
                dataIndex: 'phone'
            }],
            height: 200,

            listeners: {
                itemcontextmenu: function (grid, record, item, index, e, eOpts) {
                    e.stopEvent();
                    grid.up('grid').getGridMenu().showAt(e.getXY());
                }
            },

            renderTo: Ext.getBody(),

            getGridMenu: function () {
                var me = this;
                if (!me.contextMenu) {
                    me.contextMenu = Ext.create('Ext.menu.Menu', {
                        width: 200,
                        items: [{
                            text: 'Update',
                            handler: me.onUpdate,
                            scope: me
                        }]
                    });
                }
                return me.contextMenu;
            },

            onUpdate: function () {
                var me = this;

                Ext.MessageBox.confirm('Confirmation ', 'Are your sure ?', me.change, me);
            },

            change: function (button) {
                var me = this,
                    selectedRecEmail = me.getSelection()[0].data.email; //Retrieves selected record's email with right-click action

                if (button === "yes") {
                    return new Ext.window.Window({
                        autoShow: true,
                        title: 'Update',
                        modal: true,
                        width: 350,
                        height: 200,
                        items: [{
                            xtype: 'tbspacer',
                            height: 10
                        }, {
                            xtype: 'textfield',
                            width: 300,
                            readOnly: true,
                            value: selectedRecEmail //Display selected record email
                        }, {
                            xtype: 'textfield',
                            inputType:'password',
                            width: 300,
                            fieldLabel: 'New Password'
                        }],
                        dockedItems: [{
                            xtype: 'toolbar',
                            dock: 'bottom',
                            items: [{
                                xtype: 'tbfill'
                            }, {
                                xtype: 'button',
                                text: 'cancel',
                                listeners: {
                                    click: function (btn) {
                                        btn.up('window').destroy(); // Here is the bug: When user clicks on this button; should destroy current window but it destroys 'gridpanel' itself
                                    }
                                }
                            }, {
                                xtype: 'button',
                                text: 'save',
                                listeners: {
                                    click: function () {
                                        console.log("I'll save you!");
                                    }
                                }
                            }]
                        }]
                    });
                }
            }
        });

    }
});