Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExtJS Application Event Woes

EXTJS 4.1

I have run into a bit of a conundrum and would love to hear some other developers input on this scenario regarding ExtJS events and controller methods. I understand this topic has been covered and debated on numerous occasions but I feel that it could use a bit more delving into.

As is standard practice, I define event listeners in my Controller's init() method declaration as follows:

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
    });
}

Now, as I merrily go about coding some functionality in some other controller, I find myself needing to call showMyAwesomeView in My.controller.Awesome. I can do this in a few different ways...

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");
    }
});

To me, Approach #3 feels the most 'right'. My problem is that if I haven't instantiated the My.controller.Awesome before, the init() method has not been run yet and therefore there are no listeners established, so the fired event goes off into mystery land never to be heard of again.

I have overloaded Ext.application.getController() to call controller.init() before returning controller, therefore a controller has its init method called as soon as it is loaded (typically as a dependency in another controller). Is this bad?

In order to save on load time (my application is quite large) my controllers and their dependencies are loaded on an as-needed basis. Therefore, the majority of my controllers (and views, and data stores) are not instantiated when my application first boots therefore not init()'ed which makes firing application-wide events quite cumbersome.

I feel like I may be missing something big here, or maybe I just need to bite the bullet and ensure my controllers have been init'd before firing events. I suppose I could also put an absolutely horrific number of event listeners in the main application file and handle init'ing controllers before calling their methods accordingly, but this seems very sloppy and difficult to maintain.

Any input would be greatly appreciated, thank you for your time!

like image 206
John Hall Avatar asked May 13 '13 15:05

John Hall


1 Answers

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.

like image 117
Johnny Rice Avatar answered Sep 21 '22 16:09

Johnny Rice