EXTJS 4.1
我遇到了一个难题,并且很想听听其他开发者在这个场景中关于ExtJS事件和控制器方法的意见。我理解这个主题已经被多次讨论和辩论,但我觉得它可以使用更多的钻研。
按照标准做法,我在Controller的init()
方法声明中定义了事件监听器,如下所示:
Ext.define("My.controller.Awesome", {
init: function(application){
/** Observe some Views */
this.control({
'my-awesome-view #saveButton':{
click: this.saveMyData
}
});
/** Listen for Events, too! */
this.on({
showAwesomeView: this.showMyAwesomeView
});
/** Application events, what fun! */
this.application.on({
showThatAwesomeView: this.showMyAwesomeView
});
}
现在,我快乐地在其他控制器中编写某些功能,我发现自己需要在showMyAwesomeView
中调用My.controller.Awesome
。我可以用几种不同的方式做到这一点......
Ext.define("My.controller.Other", {
/* ... class definition */
someImportant: function(){
// I can do this (Approach #1)
this.application.getController("Awesome").showMyAwesomeView();
// Or I can do this (Approach #2)
this.application.getController("Awesome").fireEvent("showAwesomeView");
// Last but not least, I can do this (Approach #3)
this.application.fireEvent("showThatAwesomeView");
}
});
对我而言,方法#3 感觉最“正确”。我的问题是,如果我之前没有实例化My.controller.Awesome
,那么init()
方法还没有运行,因此没有建立监听器,所以被激活的事件进入神秘的土地永远不会再次听到了。
我在重新发送Ext.application.getController()
之前已经重载controller.init()
来调用controller
,因此控制器在加载后会调用其init
方法(通常作为依赖项)另一个控制器)。 这不好吗?
为了节省加载时间(我的应用程序非常大),我的控制器及其依赖项是根据需要加载的。因此,当我的应用程序首次启动因此不是init()'ed 时,我的大多数控制器(以及视图和数据存储)都没有实例化,这使得触发应用程序范围的事件非常麻烦。
我觉得我可能会遗漏一些重要的东西,或者我只需要咬紧牙关并确保我的控制器在触发事件之前已经初始化。我想我也可以在主应用程序文件中放置一个绝对可怕数量的事件监听器,并在相应地调用它们的方法之前处理init'ing控制器,但这看起来非常草率并且难以维护。
非常感谢任何意见,谢谢您的时间!
答案 0 :(得分:3)
方法#3(this.application.fireEvent('showThatAwesomeView'))是一个很好的解决方案。应用程序事件的使用导致控制器不会假设可以从与此事件相关的应用程序中添加或删除其他逻辑。
关于您对已经及时实例化以正确绑定到事件的控制器的关注,使用Ext.app.Application控制器将消除此问题。 App初始化时,App控制器初始化所有指定的控制器。您注意到与控制器数量相关的启动时间问题。我曾经在许多单页应用程序上工作,在某些情况下有数十甚至数百个控制器。将任何init逻辑保持在最低限度应该可以减少任何明显的减速。缩小和组合脚本代替按需加载已经很好地保持应用程序启动非常快。
避免使用getController方法是一种很好的做法。当使用应用程序事件代替将控制器彼此紧密耦合的逻辑时,应用程序逻辑往往更有条理。
答案 1 :(得分:0)
Ext.define('UD.controller.c1', {
extend: 'Ext.app.Controller',
refs: [
{
selector: 'viewport',
ref: 'userview'
}
],
init: function() {
console.log("initincontroller!!");
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});
},
onPanelRendered:function(){
alert("rendered");
UD.getApplication().fireEvent('myevent');
}
});
Ext.define('UD.controller.c2', {
extend: 'Ext.app.Controller',
refs: [
{
selector: 'viewport',
ref: 'userview'
}
],
init: function() {
console.log("initincontroller!!");
UD.getApplication().on({
myevent : this.doSomething
});
},
doSomething:function(){
alert("controller2");
}
});