Skip to content
Web App Solution, Inc edited this page Apr 5, 2017 · 8 revisions

Back to Wiki Home

On the Dependency Injection page, we gave an example for wiring up the FlowMVC EventDispatcher, or, event bus.

The notion of an event bus for dispatching events across applications with both local and global scope, supports the best practice of keeping objects loosely coupled. Sencha provides the Observable class which is a mixin that provides a common interface for publishing events. Classes using this mixin can use the fireEvent and fireAction methods to notify listeners of events on the class. FlowMVC has wrapped this class in the EventDispatcher class.

Here we have the function addGlobalEventListener. Developers use this function to tell the class to listen to the global event system and listen for a specific named event within a given scope.

    /**
     * Creates an event handler for a given event dispatched on the application-level event bus. Facilitates
     * inter-controller communication.
     *
     * ## Example
     *
     * this.addGlobalEventListener(CafeTownsend.event.AuthenticationEvent.LOGIN, this.onLogin, this);
     *
     * @param {String/String[]/Object} type The name or type of the event to listen for. May also be an object who's property names are
     * event names. If the event being dispatched extends FlowMVC.mvc.event.AbstractEvent, the types for the event
     * should be defined as static properties of the event itself.
     * @param {Function} handler The name or type of the event to listen for. May also be an object who's property names are
     * event names.
     * @param {Object} scope This one is important so the handler fires in the correct scope.
     */
    addGlobalEventListener: function(type, handler, scope) {
        this.logger.debug("addGlobalEventListener: " + type);

        this.addListener(type, handler, scope);

    }

Equally important, we provide a class that cleans up event listeners added via the previous function to prevent leakage:

    /**
     * Removes an event handler for a given event dispatched on the application-level event bus.
     *
     * ## Example
     *
     * this.removeGlobalEventListener(CafeTownsend.event.AuthenticationEvent.LOGIN, this.onLogin, this);
     *
     * @param {String/String[]/Object} type The name or type of the event to listen for. May also be an object who's property names are
     * event names. If the event being dispatched extends FlowMVC.mvc.event.AbstractEvent, the types for the event
     * should be defined as static properties of the event itself.
     * @param {Function} handler The name or type of the event to listen for. May also be an object who's property names are
     * event names.
     * @param {Object} scope This one is important so the handler fires in the correct scope.
     */
    removeGlobalEventListener: function(type, handler, scope) {
        this.logger.debug("removeGlobalEventListener");

        this.removeListener(type, handler, scope)
    }

If we need an object to dispatch events onto the global event system, typically the eventBus is injected into that class and the dispatchGlobalEvent function is called. FlowMVC provides an AbstractEvent type which developers extend and pass into the dispatchGlobalEvent function. This custom event is the hook used in the addGlobalEventListener to determine which events to listen for.

    /**
     * Allows for inter-controller communication by dispatching events on the application-level event bus.
     *
     * Wrapper method for <code>this.getApplication().fireEvent(eventName, args);</code>
     *
     * ## Example
     *
     * var evt = Ext.create("CafeTownsend.event.AuthenticationEvent", CafeTownsend.event.AuthenticationEvent.LOGIN, username, password);
     * this.dispatchGlobalEvent(evt);
     *
     * @param {FlowMVC.mvc.event.AbstractEvent/Object/String} event The event object to fire containing
     * a property called 'type' or a string representing the event name or type.
     * @param {Object...} args Variable number of parameters are passed to handlers. Optional and not usually used if
     * dispatching an event that subclasses FlowMVC.mvc.event.AbstractEvent.
     * @return {Boolean} Returns `false` if any of the handlers return `false`, otherwise it returns `true`.
     */
    dispatchGlobalEvent: function(event, args) {

        if(event.type != null) {
            type = event.type;
            args = event;
        } else {
            type = event;
        }

        this.logger.debug("dispatchGlobalEvent: " + type);
        return this.fireEvent(type, args);
    }