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?