sencha-logoWith ExtJS 4.2 came the awesome concept of Event Domains. Basically, these allow you to let your Controllers know about ALOT more events within your applications. For example, in 4.1, you could use the control() method within your controller to listen to component-level events. However, with Event Domains, you can now listen to events in the following domains: Global, Controller, Component, Store.

This is awesome, but there are other domains that you might want to tap. No fear, the Event Domain is easily extensible to include others!

A Proxy Domain

In my applications, I generally have a single proxy that handles all my stores’ AJAX traffic. A common event listener for the proxy is the exception event, which fires in the case of a server error response. In the past, I’ve generally just added this to the listener config of the proxy itself, and went about my business.

The problem, of course, is that you generally want to DO something when an exception occurs, such as displaying an error message, resetting the state of a store, etc. The problem with defining the listener directly on the proxy is that you have to intrude your application upon the proxy to communicate the exception beyond the proxy.

But with a custom Event Domain, we don’t need to do this anymore. Hooray!

/**
 * This class implements the data proxy event domain. All classes extending from 
 * {@link Ext.data.proxy.Proxy} are included in this domain. The selectors are simply
 * store id's or the wildcard "*" to match any store.
 *
 * @protected
 */
Ext.define('MyApp.domain.Proxy', {
    extend: 'Ext.app.EventDomain',
    singleton: true,
    requires: [
        'Ext.data.proxy.Server'
    ],
    type: 'proxy',
    idProperty: 'type',
    constructor: function() {
        var me = this;    
        me.callParent();
        me.monitor(Ext.data.proxy.Server);
    }
});

Easy-peasy. To create a custom Event Domain, we simply create a new class within our app that extends the Ext.app.EventDomain. We then define a custom type for the domain (proxy) and tell the Event Domain what property of the proxy it should use as a “selector”. Since proxies don’t have ID’s, the most logical property is probably the “type” (e.g., “rest”, “ajax”, etc). Finally, in the constructor, we tell the Event Domain to monitor() the base class of Ext.data.proxy.Server. Done.

Now, to use this, we simply have to specify the domain within our controller. In my app, I generally have a master controller for all top-level app stuff. This seems like a good place to handle global proxy error messages, so I’ll add it there:

/**
 * Main controller for all top-level application functionality
 */
Ext.define('MyApp.controller.App', {
    extend: 'MyApp.controller.Base',
    init: function() {
        this.listen({
            controller: {},
            component: {},
            global: {},
            store: {},
            proxy: {
                '#rest': {
                    exception: function( proxy, response, operation, eOpts ) {
                        console.log( 'Danger Will Robinson! We had a proxy error!' );
                    }
                }
            } 
        });
    }
});

See, nothing to it. Now, if I run my app and get a proxy exception, I can easily listen to and handle the exception event within my controller, where the handling of this error belongs.

Awesome.