【问题标题】:ExtJS: Issue with scope in classExtJS:类中的范围问题
【发布时间】:2018-11-10 14:23:48
【问题描述】:

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

这里的事情是;它应该 destroy 相关 component 与 cancel 和 no 按钮。由于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.
        }
    }
});

【问题讨论】:

    标签: extjs scope click components destroy


    【解决方案1】:

    如何将destroy方法直接指向相关组件?

    首先点击确认框按钮(No),无需销毁,点击No时自动隐藏框。

    对于更新window 而不是使用me.destroy(),您需要直接使用button.up('window').destroy(),这样它只会破坏您的更新窗口而不是grid。

    而且您也不需要在change 函数内再次调用me.onUpdate(),否则它将再次显示确认框。您可以直接在change 函数上获取所选记录,例如me.getSelection()。

    在这个 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!");
                                        }
                                    }
                                }]
                            }]
                        });
                    }
                }
            });
    
        }
    });
    

    【讨论】:

    • 亲爱的@N.Jadhav,您能否提供任何文章/书籍以阅读有关up 和类似方法来选择或绕过组件?
    • 亲爱的@N.Jadhav 我会有一个与此相关的问题;使用save 按钮我正在做Ext.Ajax.request 并使用selectedRecEmail,加上密码文本字段的输入值作为请求url 的额外参数。但是 HTTP 请求发送的电子邮件地址错误。它不能接受@ 并使用%40 代替它。如何编码?
    • 可以提供ajax请求的代码吗?我可以查看
    • 对于这个请提供任何文章/书籍来阅读 up 和类似的方法来选择或遍历组件 [ExtJS 文档](docs.sencha.com/extjs/6.5.1/index.html) 是最好的。总是喜欢这个。
    • 亲爱的@N.Jadhav 我已经解决了 Ajax 请求问题。无论如何谢谢 =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 2023-03-30
    • 2015-01-30
    • 1970-01-01
    • 2020-04-26
    相关资源
    最近更新 更多