Since all Gadgets are themselves bindings, you will certainly be working with bindings while doing Gadget development. How deeply you interact with bindings, though, is up to you.
- At one end of the spectrum, you can create only the single binding defining your Gadget, ensuring that all the necessary 'glue' code is in place (as per the examples we have in this document) and otherwise write your Gadget as if bindings did not exist.
- At the other end of the spectrum, you can define a rich set of binding classes that implement each of the various UI elements required by your Gadget.
Most Gadgets implemented to date have taken the simpler approach. Alternatively, the Live.com page has been implemented following the latter approach, using bindings to their greater potential. Depending on the complexity of what you want your Gadget to do, either approach may be the right one for you. If you are inclined to experiment, we encourage you to play around with bindings and see what they have to offer.
The basic code outline for a binding is no different from the code outline for a Gadget. (Recall
this example from above.)
If you are familiar with basic object-oriented programming, then working with bindings should be a natural extension of the basic programming tenets that you already understand. In general, it makes sense to create a new binding whenever you have a UI element that fits one of the following criteria:
- Used repeatedly within your Gadget,
- Requires complex initialization or destruction code that should be encapsulated in its own module,
- Must be updated by your code in a dynamic way after it has been added to the page, or
- Exposes custom events.
UI elements that are used repeatedly within your Gadget should always behave in the same way, and should be given a standard appearance. Rather than having repeated code throughout your Gadget module, it is easier to define a new binding for this UI element. The binding can take care of setting up the appropriate className for the element and initializing the element's contents in a standard way. Then whenever you need one of these elements within your Gadget, you can simply
instantiate the binding and all the rest of the work is done for you.
Often UI elements that contain other HTML elements can be complicated to instantiate or destroy, especially if there is JavaScript code listening for more or more events from the DOM objects. In this case it is always recommended that you encapsulate that code within its own binding to ensure tight control over destruction, and to ensure the code is well contained and more easily maintainable.
When one of your UI elements needs to be updated at runtime by some other portion of your JavaScript code, it is recommended that you wrap the element in its own binding. Then the binding can expose a public method to handle the update, keeping the internal implementation of the UI element separate from the code that needs to force the update to happen. This is especially important if the update may cause one or more DOM elements to be removed from the page, since your code will need to detach from all events on those DOM elements.
Finally, bindings allow the easy creation of custom events, which can be attached to by other JavaScript code within your Gadget. Here's a code example that shows how to publish an event from your binding. The binding defines an event
'onMouseOverLink'that any JavaScript class can attach to. The binding creates two link elements that it owns, and it coalesces the onmouseover events from those two elements into a single event that it fires.
registerNamespace("Gadget.Examples.ExampleBinding");
Gadget.Examples.ExampleBinding = function(p_elSource, p_args, p_namespace)
{
Gadget.Examples.ExampleBinding.initializeBase(this, arguments);
var m_el = p_elSource;
var m_this = this;
var m_a1 = null;
var m_a2 = null;
this.initialize = function(p_objScope)
{
Gadget.Examples.ExampleBinding.getBaseMethod(
this, "initialize", "Web.Bindings.Base").call(this, p_objScope);
m_a1 = document.createElement("a");
m_a1.innerText = "link 1";
m_a1.href = "www.live.com";
m_a1.attachEvent("onmouseover", OnMouseOverLink);
m_el.appendChild(m_a1);
m_a2 = document.createElement("a");
m_a2.innerText = "link 2";
m_a2.href = "www.live.com";
m_a2.attachEvent("onmouseover", OnMouseOverLink);
m_el.appendChild(m_a2);
}
this.dispose = function(p_blnUnload)
{
m_a1.detachEvent("onmouseover", OnMouseOverLink);
m_a2.detachEvent("onmouseover", OnMouseOverLink);
m_a1 = m_a2 = m_el = null;
Gadget.Examples.ExampleBinding.getBaseMethod(
this, "dispose", "Web.Bindings.Base").call(this, p_blnUnload);
}
function OnMouseOverLink()
{
m_this.fire("onMouseOverLink");
}
}
Gadget.Examples.ExampleBinding.registerClass("Gadget.Examples.ExampleBinding", "Web.Bindings.Base");
Gadget.Examples.ExampleBinding.Events = Web.Enum.create("onMouseOverLink");
Any code that wants to create an instance of the binding above and wire up to its events would look like this:
{
var linkContainerEl = document.createElement("div");
p_elSource.appendChild(linkContainerEl);
m_linkContainer = Web.Bindings.attachElementBindingSync(
linkContainerEl,
Gadget.Examples.ExampleBinding,
this);
m_linkContainer.attachEvent("onMouseOverLink", OnMouseOverLink);
}
function OnMouseOverLink()
{
window.alert("someone moused over a link in our link container!");
}
function CleanupLinkContainer()
{
m_linkContainer.detachEvent("onMouseOverLink", OnMouseOverLink);
m_linkContainer = null;
}