Using synchronous bidirectional communication with Controllers

August 8, 2013

In a big application, Controllers often need to communicate between each other in both directions; i.e. requesting some information and acting upon receiving it. Direct method calls are usually used for this:

Ext.define('My.controller.Foo', {
    extend: 'Ext.app.Controller',
    
    onPanelButtonClick: function(button) {
        // Before dispatching a message to Bar, we need to ask Baz
        // if it has the option we need
        var option = this.getController('Baz').getOption(button.text);
        
        // Now we can choose which Bar method to call
        if (option) {
            this.getController('Bar').openWindow(button.text, option);
        }
        else {
            this.getController('Bar').openDialog(button.text, !option);
        }
    },
    
    ...
});

With direct method call, this is very simple: just return a value from the called method. But how do we return a value from another Controller when we use events for information passing? One way would be to fire an event, have other Controller fire a return event with the information we requested, and listen to that return event. However, there is a simpler and faster approach that does not require much effort on our part. We can use the fact that JavaScript passes Arrays and Objects as a reference in function calls:

Ext.define('My.controller.Foo', {
    extend: 'Ext.app.Controller',
    
    onPanelButtonClick: function(button) {
        // Before dispatching a message to Bar, we are asking Baz
        // if it has the option we need by firing an event and
        // getting the return value synchronously
        var result = {};
        
        this.fireEvent('getBazOption', result);
        
        if (result.option) {
            ...
        }
    },
    
    ...
});

Ext.define('My.controller.Baz', {
    extend: 'Ext.app.Controller',
    
    init: function() {
        this.listen({
            controller: {
                '*': {
                    getBazOption: 'getBazOption'
                }
            }
        });
    },
    
    getBazOption(result) {
        result.option = this.option;
    },
    
    ...
});

This approach can be used along with class inheritance, with superclasses setting default values and subclasses overriding them if needed; it can also be used to collect information from more than one Controller in one go. Since event handlers are executed synchronously, we can avoid callbacks and have very simple and easy to follow application logic. Synchronous function calls are also much easier to debug than asynchronous callbacks.

tags: , , ,
posted in Software development by nohuhu

Follow comments via the RSS Feed | Leave a comment | Trackback URL

Leave Your Comment

 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org