1

我的 EXTJS 应用程序中有一个删除按钮。单击按钮时,我会打开一个确认表单,询问用户他们是否确定要删除该项目。删除按钮是我的应用程序中许多表单的一部分。无论使用何种形式,我都会打开确认窗口。

在确认窗口中单击“是”按钮时,我想做一些操作。但是这些操作必须特定于首先打开的表单。所以,我很困惑如何使用相同的视图、相同的按钮,但不同的操作取决于打开的第一个表单。

查看:这是在任何表单中单击删除按钮时打开的窗口

  Ext.define('app.view.GenMessageWin', {
extend : 'Ext.panel.Panel',
alias : 'widget.genmessagewin',

  var fp = {
        xtype : 'panel',
        itemId : 'MSGPANEL',
        width : Width,
        height : 150,
        cls : 'msg effect1',
        layout : 'form',
        border : false,
        items : [{
            xtype : 'panel',
            //cls : 'winTitle',
            html : msgTxt,
            border : 0
        }, {
            xtype : 'form',
            itemId : 'MSGFORM',
            border : false,
            title : '',
            buttonAlign : 'center',
            fieldDefaults : {
                msgTarget : 'side',
                labelWidth : 110,
                size : 30
            },

            buttons : [{
                text : LANG.BTYES,
                iconCls : 'icon-tick-tb',
                iconAlign : 'right',
                cls : 'tip-btn',
                action : 'delete',
                id : 'BTYES'
            }, {
                text : LANG.BTNO,
                iconCls : 'icon-cross-tb',
                iconAlign : 'right',
                cls : 'tip-btn',
                action : 'notDelete',
                id : 'BTNO'
            } ]

控制器

        init : function() {

         this.control({

        'button[action = delete]' : {
            click : this.delete
        },
        'button[action = notDelete]' : {
            click : this.notDelete
        },

因此,在删除动作中,我们首先要确定打开了哪个表单,然后相应地删除数据。

4

4 回答 4

2

您有 3 个选项:

1)使选择器更具体:

'form1 button[action=delete]': {
    click: this.form1Delete
},

form1Delete: function(){
    this.showMsg(function() {
        // form 1 delete
    });
}

2)回溯组件层次结构,找到打开的表单

onDelete: function(btn) {
    var form = btn.up('form'); // find an xtype form or subclass
    if (form.someCondition) {
       //foo
    } else {
        //bar
    }
}

3) 正如德米特里所建议的那样。您需要将其转换为“MVC 样式”。

Ext.define('ConfirmButton', {
    extend: 'Ext.button.Button',

    title: '',
    msg: '',

    requires: ['Ext.window.MessageBox'],

    initComponent: function(){
        this.callParent();
        this.on('click', this.handleClick, this);
    },

    handleClick: function(){
        Ext.MessageBox.confirm(this.title, this.msg, this.checkResponse, this);
    },

    checkResponse: function(btn){
        if (btn == 'yes') {
            this.fireEvent('confirm', this);
        }
    }
});

Ext.onReady(function(){

    var btn = new ConfirmButton({
        renderTo: document.body,
        text: 'Foo',
        title: 'Should I',
        msg: 'Are you sure'
    });

    btn.on('confirm', function(){
        console.log('Do something');
    })

});
于 2012-09-10T11:34:47.997 回答
1

我认为您应该在按钮中嵌入“确认”功能,即创建您自己的ConfirmButton类,只有当对话框以“是”退出时,才会在按下并执行传递的处理程序时首先触发一个对话框。

这是示例实现:

Ext.define('My.ConfirmButton',  {
    extend: 'Ext.button.Button',
    alias: 'widget.confirmbutton',

    dlgConf: {
        title: 'Are you sure?',
        msg: 'Are you sure you want to delete this?',
        buttons: Ext.Msg.YESNO,
        closable: false
    },

    initComponent: function() {
        this.callParent(arguments);
        // remember the originally passed handler
        this.origHandler = this.handler;
        this.origScrope = this.scope;

        // override current handler to fire confirmation box first
        this.handler = this.confirmHandler;
        this.scope = this;
    },

    confirmHandler: function(me, e) {
        // show dialog and call the original handler only on 'yes'
        Ext.Msg.show(Ext.applyIf({
            fn: function(buttonId) {
                if(buttonId == 'yes') {
                    me.origHandler && me.origHandler.call(me.origScope || me, me, e)
                }
            },
            scope: me
        }, this.dlgConf))
    },

    // Method used to dynamically reassign button handler
    setHandler: function(handler, scope) {
        // remember the originally passed handler
        this.origHandler = this.handler;
        this.origScrope = this.scope;

        // override current handler to fire confirmation box first
        this.handler = this.confirmHandler;
        this.scope = this;

        return this;
    },
});

这是示例用法:

Ext.create('My.ConfirmButton', {
    text: 'Delete me',
    renderTo: Ext.getBody(),
    handler: function() {
        alert('Aww, you deleted something! :(')
    }
});

如您所见,确认逻辑对外界是隐藏的,您使用此按钮的方式与使用常规 Ext.Button 完全相同(通过将 a 传递handler给它)。此外,您可以覆盖按钮触发的对话框的配置(您可能希望根据需要对其进行调整,例如允许将记录名称传递给对话框以获得更友好的 UI)。

请注意,代码未经过彻底测试,某些情况可能未被发现。

UPD。您需要在组件类定义中添加一个alias(former xtype),以便您可以在控制器代码的 ComponentQuery 中使用它,例如

this.control({
    'confirmbutton[action = delete]' : {
        click : this.delete
    },
    'confirmbutton[action = notDelete]' : {
        click : this.notDelete
    }
})
于 2012-09-10T11:38:17.730 回答
1

我正在做类似的事情;我只是使用原生的 Ext.Msg 类

控制器代码

,onDelete: function() {
    var me = this;
    Ext.Msg.show({
        title:'Really shure?',
        msg: 'Really wanna do this?',
        buttons: Ext.Msg.YESNO,
        icon: Ext.Msg.QUESTION,
        closable: false,
        fn: function(btn) {
            if (btn == 'yes') {
                me.deleteRecord();
            }
        },
        scope: me
    });
}
,deleteRecord: function() {
    var me = this,
        store = Ext.StoreMgr.lookup('datastore');
    store.remove(me.selectedRecord);
    store.sync();
}

我建议您将所有与此相关的逻辑保留在控制器中。在你的情况下,这似乎没问题,因为你只是捕捉按钮事件。如果您使用完全相同的窗口,您的问题可能是所有控制器都捕获了这些。

例如,您可以通过在创建窗口时动态创建操作属性值来解决此问题。喜欢action='onDeleteCar'

于 2012-09-10T11:32:37.357 回答
0

我使用的最终解决方案是使用全局命名空间声明变量,以便可以从任何地方访问它们。在打开第一个表单时,我使用记录变量从表单中获取数据,并为它们分配一个全局名称,例如

App1.Var1 = record.data.id;

并且,在打开删除窗口时,单击按钮时 App1.Var1 可以访问这些变量。

于 2012-09-19T09:23:51.767 回答