javascriptdom-eventsgoogle-closure-library

Having a class be a goog.events.EventHandler and a goog.events.EventTarget


I have a view class that listen to events on DOM elements. It also fires events that the controller listens to.

How does that best work with Google Closure's library?

Here's my best shot.

/**
 * @constructor
 * @extends {goog.events.EventHandler}
 * @implements {goog.events.Listenable}
 */
var MyViewClass = function() {
    goog.events.EventHandler.call(this);
    goog.events.EventTarget.call(this);
};
goog.inherits(MyViewClass, goog.events.EventHandler);
goog.object.extend(MyViewClass, goog.events.EventTarget);

Is there a better way? My use case seems reasonable. Is it?


Solution

  • I found a class in the Google Closure Library that does a similar thing: goog.events.FileDropHandler.

    It both listens for and fires events. The relevant parts of the source code:

    /**
     * @constructor
     * @extends {goog.events.EventTarget}
     */
    goog.events.FileDropHandler = function(element, opt_preventDropOutside) {
      goog.events.EventTarget.call(this);
      this.eventHandler_ = new goog.events.EventHandler(this);
    };
    goog.inherits(goog.events.FileDropHandler, goog.events.EventTarget);
    
    goog.events.FileDropHandler.prototype.disposeInternal = function() {
      goog.events.FileDropHandler.superClass_.disposeInternal.call(this);
      this.eventHandler_.dispose();
    };
    

    Thus, it extends goog.events.EventTarget, but the handler is a different object. This seems to follow a pattern in other classes in the Closure Library as well.


    I think I would prefer using registerDisposable from the goog.Disposable superclass instead of overriding disposeInternal, but the idea is the same.

    /**
     * @constructor
     * @extends {goog.events.EventTarget}
     */
    var MyViewClass = function() {
        goog.events.EventTarget.call(this);
        this.handler = new goog.events.EventHandler();
        this.registerDisposable(this.handler);
    };
    goog.inherits(MyViewClass, goog.events.EventTarget);