7

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()controllerinit

为了节省加载时间(我的应用程序非常大),我的控制器及其依赖项是根据需要加载的。因此,当我的应用程序首次启动时,我的大多数控制器(以及视图和数据存储)都没有被实例化,因此没有 init()'ed,这使得触发应用程序范围的事件非常麻烦。

我觉得我可能在这里遗漏了一些重要的东西,或者我只需要硬着头皮确保我的控制器在触发事件之前已经被初始化。我想我也可以在主应用程序文件中放置绝对数量惊人的事件侦听器,并在相应地调用它们的方法之前处理初始化控制器,但这似乎非常草率且难以维护。

任何意见将不胜感激,感谢您的宝贵时间!

4

2 回答 2

3

Approach #3 (this.application.fireEvent('showThatAwesomeView')) is a great solution. The use of application events results in controllers that have no assumptions about what other logic may be added or removed from the application related to this event.

Regarding your concern about controllers having been instantiated in time to be correctly bound to events, use of the Ext.app.Application controller will eliminate this. The App controller initializes all specified controllers when the App initializes. You noted a concern about start-up time related to the number of controllers. I have worked on many single page apps that have dozens and even hundreds of controllers in some cases. Keeping any init logic to a minimum should reduce any noticeable slowdown. Minified and combined scripts in place of on-demand loading has worked well to keep app start-up very fast.

Avoiding the getController method is good practice. Application logic tends to be better organized when using application events in place of logic that tightly couples controllers with each other.

于 2013-05-13T18:21:29.917 回答
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");
    }
});
于 2014-01-30T13:18:22.650 回答