Extjs MVC嵌套视图事件和异步函数

我正在开发一个extJS 4.2 MVC应用程序。 我有这个上下文菜单视图对象定义:

Ext.define('XApp.view.message.inbox.CtxMenu', {
    extend : 'Ext.menu.Menu',
    alias : 'widget.inboxctxmenu',
    items : [ {
        itemId : 'buttonSetFlags',
        text : 'ToRead'
    }]
});

这个上下文菜单是当我创建这个网格(和其他我的扩展网格)时建立的:

Ext.define('XApp.view.message.inbox.Grid', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.inboxgrid',
    store: 'message.Inbox',

    initComponent : function(){
        this.menu = this.buildMenu();
        this.callParent(arguments);
        this.on({
            scope : this,
            itemcontextmenu : this.onItemContextMenu
        });
    },

    onItemContextMenu : function(grid, record, item, index, e, eOpts) {
        console.log('onItemContextMenu');
        e.stopEvent();      
        this.menu.showAt(e.getXY());
    },

    onDestroy : function(){
        console.log('destroy grid and menu');
        this.menu.destroy();
        this.callParent(arguments);
    },

    buildMenu : function(){
        return Ext.widget('inboxctxmenu');
    }
});

此代码是从Sencha博客的第2点中提取的,以避免嵌套对象上的内存泄漏。 现在在我的控制器中,我想听

Ext.define('XApp.controller.Inbox', {
    extend : 'Ext.app.Controller',

    init : function(application) {
        this.control({
            "inboxctxmenu #buttonSetFlags" : {
                click : this.onFlagsSetter
            }
        });
    },
    onFlagsSetter : function(button, e, eOpts) {
        this.getController('Message').SetMessageStatus(1,"ToRead",this.getStore('message.Inbox').load);
    }
});

在这个控制器中,我调用另一个控制器函数,我想重新加载'message.Inbox'store:

Ext.define('XApp.controller.Message', {
    extend : 'Ext.app.Controller',

    SetMessageStatus: function(id,statusToSet,callback) {
        Ext.Ajax.request({
            url : XApp.util.Util.serverUrl + 'api/message/SetMessageStatus/' + id + "/" + statusToSet,
            method : "GET",
            failure : function(response, options) {
                console.log('Failure' + response);
            },
            success : function(conn, response, options, eOpts) {
                console.log('Success');
                if (callback && typeof(callback) === "function") {  
                    console.log('Calling callback');
                    callback();  
                }  
            }
        });
    }
});

在这个函数中,我使用AJAX进行异步调用,并且我想在ajax响应之后重新加载InboxController的存储,但是使用这种表示法,控制台会抛出错误。 有最佳实践来调用异步函数并在成功或失败后启动回调? 另一个问题是:什么是ExtJs MVC监听嵌套视图事件的最佳实践(例如,我的ctxmenu嵌套在网格中)? 我读了fireevent和bubbleevent,但我很困惑...请带我回到正确的方式...


JFYI示例中的上下文菜单不嵌套在网格中。 菜单是浮动对象,因此它们不在通常的组件层次结构中。

您遇到的错误是因为您没有将回调传递给SetMessageStatus ,所以您将表达式的结果传递给this.getStore('message.Inbox').load - 该函数计算为函数,但没有范围限制它没用。 阅读这个问题的答案以获得关于函数范围的更多解释。

用一种天真的正面方法,修复程序看起来如此:

onFlagsSetter: function(button, e) {
    var me = this; // Important for the closure below

    this.getController('Message').SetMessageStatus(1, 'ToRead', function() {
        // Note that within the callback function, `this` is an object
        // entirely different from `this` in the above line, so we call
        // `getStore` on the captured scope instead.
        me.getStore('message.Inbox').load();
    });
}

但是,更好的方法是使用Controller事件:

Ext.define('XApp.controller.Inbox', {
    extend: 'Ext.app.Controller',

    init: function() {
        this.listen({
            component: {
                'inboxctxmenu #buttonSetFlags': {
                    click: this.onFlagsSetter
                }
            },
            controller: {
                '*': {
                    statusmessage: this.onStatusMessage
                }
            }
        });
    },

    onFlagsSetter: function(button) {
        this.fireEvent('setstatus', 1, 'ToRead');
    },

    onStatusMessage: function(success, response) {
        if (success) {
            this.getStore('message.Inbox').load();
        }
    }
});

Ext.define('Xapp.controller.Message', {
    extend: 'Ext.app.Controller',

    init: function() {
        this.listen({
            controller: {
                '*': {
                    setstatus: this.setMessageStatus
                }
            }
        });
    },

    setMessageStatus: function(id, statusToSet) {
        Ext.Ajax.request({
            url: ...,
            method: 'GET',

            failure: function(response) {
                this.fireEvent('statusmessage', false, response);
            },

            success: function(connection, response) {
                this.fireEvent('statusmessage', true, response);
            },

            // We are setting the above callbacks' scope to `this` here,
            // so they would be bound to the Controller instance
            scope: this
        });
    }
});

正如你所看到的,通过使用Controller事件,我们已经从Message控制器中分离了Inbox控制器; 他们不再直接调用对方的方法,而是传递信息。 代码更清晰,关注点分开。

链接地址: http://www.djcxy.com/p/76399.html

上一篇: Extjs MVC nested views events and async function

下一篇: how to create interceptor like functionality for buttons in extjs 4.0?