ExtjsMVC嵌套视图事件和异步函数
Extjs MVC nested views events and async function
我正在开发一个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.Inpinbox"存储:
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();
});
}
然而,更好的方法是使用控制器事件:
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
});
}
});
正如您所看到的,通过使用控制器事件,我们将收件箱控制器与消息控制器解耦;它们不再直接调用彼此的方法,而是传递信息。代码要干净得多,而且关注点也得到了适当的分离。
相关文章:
- 如何在异步函数中使用javascript对象
- Meteor:异步函数回调异常:onAfterAction
- 未调用jquery异步函数
- 使用来自不同异步函数的响应创建一个json对象
- 如何在异步函数中正确使用Promise.all()和then()
- 从异步函数返回值
- 如何按照承诺使用mocha/chai/chai测试ES7异步函数
- 如何在将Node异步函数转换为promise时使用Q库
- 如何在异步函数与Deferredjquery之间同步
- ng用异步函数模拟怪异行为
- 用mocha测试异步函数
- 用于异步函数中的循环和定时问题
- Node.js设计:多个异步函数使用作为闭包传递的函数写入数据库
- 嵌套异步函数未及时返回数据的问题
- 在异步函数中维护变量的状态
- 递归异步函数
- Bluebird promisifyAll不会创建整个异步函数集
- 递归调用异步函数
- 异步函数调用是否可以在两个同步语句之间完成
- 如何在nodejs中实现异步函数