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

You have 3 options:

1) Make the selector more specific:

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

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

2) Traverse back up the component hierarchy and find the open form

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

3) As suggested by Dmitry. You'll need to convert it over to 'MVC style'.

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

I am doing something similar; I simply use the native Ext.Msg class

Controller code

,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();
}

I would recommend you to keep all logic concerning this within the controller. I your case it'seems that's no problem, cause you just catching the button-events. You problem may be that all controllers catch these, if you are using totally the same window.

You can solve this for example by creating the action property value dynamically when creating the window. Like action='onDeleteCar'

于 2012-09-10T11:32:37.357 に答える
1

I think you should embed the 'confirmation' functionality inside the button, i.e. create your own ConfirmButton class that would first fire a dialog upon pressing and executing the passed handler only if the dialog exited with "yes".

Here is the example implementation:

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;
    },
});

Here is the sample usage:

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

As you see, the confirmation logic is hidden from the outside world, you use this button exactly like you would use a regular Ext.Button (by passing a handler to it). Also, you can override the configuration of the dialog that the button fires (you may want to adjust it to your needs, e.g. allow passing record name to the dialog for a friendlier UI).

Note that the code isn't thoroughly tested, some cases might be left uncovered.

UPD. You need to add an alias (former xtype) to the component class definition so you can use it in ComponentQuery in your controller code, e.g.

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

The final solution that i used was to declare variables using the global namespace so that they can be accessed from anywhere. On opening the first form, i get the data from the form using the record variable, and assign them a global name like

App1.Var1 = record.data.id;

And, on opening the delete window, these variables can be accessed by App1.Var1 when the buttons are clicked.

于 2012-09-19T09:23:51.767 に答える