What is a good generic sibling control Javascript communication strategy?
- by James
I'm building a webpage that is composed of several controls, and trying to come up with an effective somewhat generic client side sibling control communication model. One of the controls is the menu control. Whenever an item is clicked in here I wanted to expose a custom client side event that other controls can subscribe to, so that I can achieve a loosely coupled sibling control communication model.
To that end I've created a simple Javascript event collection class (code below) that acts as like a hub for control event registration and event subscription. This code certainly gets the job done, but my question is is there a better more elegant way to do this in terms of best practices or tools, or is this just a fools errand?
/// Event collection object - acts as the hub for control communication.
function ClientEventCollection()
{
this.ClientEvents = {};
this.RegisterEvent = _RegisterEvent;
this.AttachToEvent = _AttachToEvent;
this.FireEvent = _FireEvent;
function _RegisterEvent(eventKey)
{
if (!this.ClientEvents[eventKey])
this.ClientEvents[eventKey] = [];
}
function _AttachToEvent(eventKey, handlerFunc)
{
if (this.ClientEvents[eventKey])
this.ClientEvents[eventKey][this.ClientEvents[eventKey].length] = handlerFunc;
}
function _FireEvent(eventKey, triggerId, contextData )
{
if (this.ClientEvents[eventKey])
{
for (var i = 0; i < this.ClientEvents[eventKey].length; i++)
{
var fn = this.ClientEvents[eventKey][i];
if (fn)
fn(triggerId, contextData);
}
}
}
}
// load new collection instance.
var myClientEvents = new bsdClientEventCollection();
// register events specific to the control that owns it, this will be emitted by each respective control.
myClientEvents.RegisterEvent("menu-item-clicked");
Here is the part where this code above is consumed by source and subscriber controls.
// menu control
$(document).ready(function()
{
$(".menu > a").click( function(event)
{
//event.preventDefault();
myClientEvents.FireEvent("menu-item-clicked", $(this).attr("id"), null);
});
});
<div style="float: left;" class="menu">
<a id="1" href="#">Menu Item1</a><br />
<a id="2" href="#">Menu Item2</a><br />
<a id="3" href="#">Menu Item3</a><br />
<a id="4" href="#">Menu Item4</a><br />
</div>
// event subscriber control
$(document).ready(function()
{
myClientEvents.AttachToEvent("menu-item-clicked", menuItemChanged);
myClientEvents.AttachToEvent("menu-item-clicked", menuItemChanged2);
myClientEvents.AttachToEvent("menu-item-clicked", menuItemChanged3);
});
function menuItemChanged(id, contextData)
{
alert('menuItemChanged ' + id);
}
function menuItemChanged2(id, contextData)
{
alert('menuItemChanged2 ' + id);
}
function menuItemChanged3(id, contextData)
{
alert('menuItemChanged3 ' + id);
}