ExtJS应用程序事件灾难
extjs4.1 我遇到了一个难题,我很想听听其他开发人员对这个场景中有关ExtJS事件和控制器方法的意见。我知道这个话题已经在很多场合被讨论过了,但我觉得可以再深入一点 按照标准惯例,我在控制器的ExtJS应用程序事件灾难,extjs,extjs4,extjs-mvc,Extjs,Extjs4,Extjs Mvc,extjs4.1 我遇到了一个难题,我很想听听其他开发人员对这个场景中有关ExtJS事件和控制器方法的意见。我知道这个话题已经在很多场合被讨论过了,但我觉得可以再深入一点 按照标准惯例,我在控制器的init()方法声明中定义事件侦听器,如下所示: Ext.define("My.controller.Awesome", { init: function(application){ /** Observe some Views */ this.control({ 'm
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
});
}
现在,当我兴致勃勃地在其他一些控制器中编写一些功能时,我发现自己需要在My.controller.Awesome
中调用showmayawesomeview
。我可以用几种不同的方法来做
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()
方法还没有运行,因此没有建立监听器,因此激发的事件会进入神秘地带,再也听不到了
在返回controller
之前,我重载了Ext.application.getController()
来调用controller.init()
,因此一个控制器在加载后立即调用其init
方法(通常作为另一个控制器中的依赖项)这不好吗?
为了节省加载时间(我的应用程序相当大),我的控制器及其依赖项将根据需要加载。因此,我的大多数控制器(以及视图和数据存储)在我的应用程序首次启动时没有实例化,因此没有init()'ed,这使得触发应用程序范围的事件非常麻烦
我觉得我可能错过了一些重要的东西,或者我需要咬紧牙关,确保我的控制器在触发事件之前已经启动。我想我也可以在主应用程序文件中放入数量绝对惊人的事件侦听器,并在相应地调用其方法之前处理初始化控制器,但这似乎非常草率,而且很难维护
如果您有任何意见,我们将不胜感激,谢谢您的宝贵时间 方法#3(this.application.firevent('showthawasomeview'))是一个很好的解决方案。应用程序事件的使用会导致控制器对与此事件相关的应用程序中可能添加或删除的其他逻辑没有任何假设
考虑到您对控制器已被及时实例化以正确绑定到事件的担忧,使用Ext.app.Application controller将消除这一问题。应用程序控制器在应用程序初始化时初始化所有指定的控制器。您注意到与控制器数量相关的启动时间问题。我曾在许多单页应用程序上工作过,在某些情况下,这些应用程序有几十个甚至数百个控制器。将任何init逻辑保持在最小值应该可以减少任何明显的减速。小型化和组合式脚本取代了按需加载,能够很好地保持应用程序的快速启动
避免使用getController方法是一种很好的做法。当使用应用程序事件来代替控制器之间紧密耦合的逻辑时,应用程序逻辑往往组织得更好。有趣的是,我想您觉得方法3是最好的,因为它是最解耦的,控制器2不必关心哪个控制器应该执行它所需的操作。但是,除非控制器已经可用,否则必须有人知道。。也许您可以在应用程序级别创建某种路由表(哪个控制器侦听哪些事件),并让fireEvent init成为所需的控制器?@AmitAviv我在问题中简要介绍了路由思想,但是,在主应用程序文件中有大量侦听器列表,仅仅是为了确保在调用所需方法之前实例化控制器,这似乎非常草率。我宁愿在触发事件之前手动实例化控制器(在被调用的控制器中)。谢谢你的意见!我不是指一个庞大的侦听器列表,我是指一个表,键是事件名,值是控制器名。。可以重载fireEvent以读取表并基于表初始化所需的控制器。我不确定这是不是一个很好的解决方案,但我没有看到一个神奇的方法来保持解耦和延迟加载,没有人知道“事件控制器”的关系..我的意思是O,正如可怕的问题+1..我完全同意你的建议,尽管我仍然担心在应用程序发布时必须加载所有控制器。由于数据存储的加载通常是瓶颈(我想?),也许我需要设计一种只加载某些数据存储的方法,并且只在需要时加载其他数据存储。我暂时不回答这个问题,但我会在其他回答之前将你的答案标记为正确。非常感谢您的投入!好的,太好了。延迟数据加载对加速初始应用程序加载也很有帮助。我接受了你的回答,再次感谢。如果您愿意提供您的输入,我发布了一个关于复杂保存操作的相关问题:)
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");
}
});