Permalink
Browse files

add in mediator

  • Loading branch information...
1 parent 2b99043 commit c2d71972b40c2befd19bec0d73449744ee5ebe99 @rhysbrettbowen committed Mar 13, 2012
Showing with 150 additions and 0 deletions.
  1. +14 −0 README.md
  2. +136 −0 mediator.js
View
@@ -103,8 +103,22 @@ This is an interface that should have a custom implementation. Two simple implem
mvc.Router uses goog.History and hash tokens to hold and manage the state of the application. You can define a route with a regular expression that will fire custom events when a certain route comes on the URL.
+## mvc.Mediator ##
+
+mvc.Mediator allows message passing between components. It's a singleton so you get it's reference using
+
+```javascript
+var mediator = mvc.Mediator.getInstance();
+```
+
+you can then register your object with the mediator and the messages that you may pass. This allows other modules that are listening for a specific message to run some initiation, or dispose when you unregister. You can listen to messages using the on method and stop using the off method. You can even test to see if anyone is listening for a message using the isListened method
+
### changelog ###
+#### v0.7 ###
+
+- add in mvc.Mediator
+
#### v0.6 ####
- split format function up to format, alias and meta
View
@@ -0,0 +1,136 @@
+// goog.mvc 0.7
+
+// (c) 2012 Rhys Brett-Bowen, Catch.com
+// goog.mvc may be freely distributed under the MIT license.
+// For all details and documentation:
+// https://github.com/rhysbrettbowen/goog.mvc
+
+goog.provide('mvc.Mediator');
+
+goog.require('goog.array');
+goog.require('goog.object');
+
+/**
+ * @constructor
+ */
+mvc.Mediator = function() {
+ /** @private */
+ this.available_ = {};
+ /** @private */
+ this.listeners_ = {};
+};
+
+goog.addSingletonGetter(mvc.Mediator);
+
+
+/**
+ * @param {Object} obj
+ * @param {Array.<string>} messages
+ */
+mvc.Mediator.prototype.register = function(obj, messages) {
+ // each message we save the object reference in an array so we know it
+ // can provide that message
+ goog.array.forEach(messages, function(message) {
+ this.available_[message] = this.available_[message] || [];
+ goog.array.insert(this.available_[message], obj);
+ // if we registered any listeners for a message that can now start we
+ // fire it with the object
+ if(this.available_[message].length == 1 && this.listeners_[message]) {
+ goog.array.forEach(this.listeners_[message], function(listener) {
+ if(listener.init)
+ listener.init(obj);
+ });
+ }
+ }, this);
+};
+
+/**
+ * @param {Object} obj
+ * @param {Array.<string>=} opt_messages
+ */
+mvc.Mediator.prototype.unregister = function(obj, opt_messages) {
+ // remove the object from all available
+ goog.object.forEach(this.available_, function(val, key) {
+ // if it's not in the messages to remove then skip
+ if(opt_messages && !goog.array.contains(opt_messages, key))
+ return;
+ // remove and if the last to be removed from a message call dispose
+ // methods for listening objects
+ if(goog.array.remove(val, obj) && !val.length) {
+ if(this.listeners_[key]) {
+ goog.array.forEach(this.listeners_[key], function(listener) {
+ if(listener.dispose)
+ listener.dispose(obj);
+ });
+ }
+ delete this.available_[key];
+ }
+ }, this);
+};
+
+/**
+ * the message to listen for and the handler. Can either be a function to run
+ * or an object of the type: {init:Function, fn:Function, dispose:Function}
+ * which will run init when the message becomes available and dispose when
+ * a message is no longer supported. Returns a uid that can be used with
+ * off to remove the listener
+ *
+ * @param {string} message
+ * @param {Object|Function} handler
+ */
+mvc.Mediator.prototype.on = function(message, handler) {
+ this.listeners_[message] = this.listeners_[message] || [];
+ if(!this.listeners_[message].length) {
+ if(handler.init && this.available_[message]) {
+ handler.init(this.available_[message][0]);
+ }
+ }
+ goog.array.insert(this.listeners_[message], handler);
+ return goog.getUid(handler);
+};
+
+/**
+ * @param {number} uid
+ */
+mvc.Mediator.prototype.off = function(uid) {
+ goog.object.forEach(this.listeners_, function(listener) {
+ goog.array.removeIf(listener, function(el) {
+ return goog.getUid(el) == uid;
+ });
+ });
+};
+
+/**
+ * @param {string} message
+ * @return {boolean}
+ */
+mvc.Mediator.prototype.isListened = function(message) {
+ return !!this.listeners_[message];
+};
+
+/**
+ * @param {string} message
+ * @param {*=} opt_args
+ */
+mvc.Mediator.prototype.broadcast = function(message, opt_args) {
+ if(!this.listeners_[message])
+ return;
+ goog.array.forEach(this.listeners_[message], function(listener) {
+ if(goog.isFunction(listener)) {
+ listener(opt_args);
+ } else if (listener.fn) {
+ listener.fn(opt_args);
+ }
+ });
+};
+
+mvc.Mediator.prototype.reset = function() {
+ this.available_ = {};
+ goog.object.forEach(this.listeners_, function(listener) {
+ goog.array.forEach(listener, function(l) {
+ if(l.dispose)
+ l.dispose();
+ });
+ });
+ this.listeners_ = {};
+};

0 comments on commit c2d7197

Please sign in to comment.