public
Last active

Mediator pattern

  • Download Gist
example.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// Example 1
mediator.name = 'Doug';
mediator.subscribe('nameChange', function(arg){
console.log(this.name);
this.name = arg;
console.log(this.name);
});
 
mediator.publish('nameChange', 'Jorn');
 
 
// Example 2
var obj = { name : 'John' };
mediator.installTo(obj);
 
obj.subscribe('nameChange', function(arg){
console.log(this.name);
this.name = arg;
console.log(this.name);
});
 
obj.publish('nameChange', 'Sam');
mediator.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
var mediator = (function(){
var subscribe = function(channel, fn){
if(!mediator.channels[channel]) mediator.channels[channel] = [];
mediator.channels[channel].push({ context : this, callback : fn });
return this;
};
var publish = function(channel){
if(!mediator.channels[channel]) return false;
var args = Array.prototype.slice.call(arguments, 1);
for(var i = 0, l = mediator.channels[channel].length; i < l; i++){
var subscription = mediator.channels[channel][i];
subscription.callback.apply(subscription.context.args);
};
return this;
};
return {
channels : {},
publish : publish,
subscribe : subscribe,
installTo : function(obj){
obj.subscribe = subscribe;
obj.publish = publish;
}
};
}());

Related:

diff --git a/example.js b/example.js
index 2859683..3f6e4da 100644
--- a/example.js
+++ b/example.js
@@ -7,7 +7,7 @@ mediator.subscribe('nameChange', function(arg){
      console.log(this.name);
 });

-madiator.publish('nameChange', 'Jorn');
+mediator.publish('nameChange', 'Jorn');


 // Example 2

@timrchavez thanks!

Newbie to JS, Backbone and all things related but does this mean that the backbone-aura application is up for an update? Using it as a template.

thanks for sharing.Can i ask a questin that why i copy the excatly same code then run it, in the console panel of chrome i get the message of undefined?So why?

line 12 should read ...

subscription.callback.apply(subscription.context.args, args);

to pass the arguments to the subscribing function otherwise you get undefined

It's actually:

subscription.callback.apply(subscription.context, args);

The context is saved with the channel for the purpose of being passed as "this" to the callback. Since subscription.context.args does not exist it will actually pass the window object as "this" to the callback. One of the pitfalls of javascript.

Even with that fix, something seems wrong.

I'm not sure, but I think the intention was to give each channel a unique context based off the mediator object at the time it was being "subscribed".

However, by assigning "this" to the context property in line 4, you are essentially linking every context to the same object. Thus, defeating the whole purpose of saving the context with each channel.

In order to make each context refer to the object at the time it was "subscribed", and not at the time it was "published", the object must be cloned at the time of subscription, using something like jQuery extend.

However, since this is a design pattern it should avoid using anything other than plain JavaScript. You would have to use a for-in loop to copy the properties to a clone object like so:

      var that = {};
      for(var property in this){
        that[property] = this[property];
      }

However, I might not be fulling grasping the idea of this pattern.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.