If you have read into the ASP.NET AJAX framework and the
AJAX Control Toolkit, you know that Microsoft built into the ASP.NET AJAX
framework a client library of components that make developing AJAX controls and
extenders easier. The script, for the most part, follows a common makeup, and
this basic makeup can be easily generated via CodeSmith. This script requires
more explanation, so bear with me on it.
The JavaScript structure is expressed in a specific way. At
the beginning is the creation of the namespace. The next section is the
creation of the class, with a constructor, properties, methods, and event
handlers. Following this is the event handlers that tap into the base DOM element
events. Last is the definition of the prototype, descriptor, and the
registration of the class.
If you are not familiar with this model of writing
JavaScript and are not sure what I mean, you may want to read a few other
articles on the subject. I have attached a couple for you to understand the
base structure.
http://www.asp.net/ajax/documentation/live/tutorials/EnhancingJavaScriptTutorial.aspx
http://www.asp.net/AJAX/Documentation/Live/tutorials/ExtenderControlTutorial1.aspx
http://www.asp.net/AJAX/Documentation/Live/tutorials/IScriptControlTutorial1.aspx
To begin, my script contains the following properties:
·
ObjectNamespace - The namespace of the object. The ASP.NET AJAX
framework mimics ASP.NET framework by including namespace registration.
·
ObjectName - The name of the class.
·
InheritedObjectName - The name of the base class that the
JavaScript inherits from. Some of the options are Sys.UI.Component,
Sys.UI.Control, Sys.UI.Behavior, and other classes that you derive.
·
Properties - A string collection that contains the properties
that the AJAX class exposes. Both getters and setters are exposed.
·
ExposedEvents - A string collection of events that the class
exposes; events can be raised from the JavaScript class.
·
EventsListenedTo - The JavaScript class taps into the events of the
DOM element that it extends. For instance, a text element has key and mouse
events that are raised, which the JavaScript class can listen to. These are the
events that the class taps into.
I am going to skip the namespace registration and head right
into the constructor. The following is the definition of the constructor in the
script.
Listing 14
<%= this.GetAjaxClassName(false) %> =
function <%= this.GetAjaxClassName(true) %>(associatedElement)
{
<%= this.GetAjaxClassName(false)%>.initializeBase(associatedElement);
<%
foreach (string property in this.Properties)
{
%>
this.<%= this.GetVariableName(property) %> = null;
<%
}
%>
<%
foreach (string listenedEvent in this.EventsListenedTo)
{
%>
this.<%= this.GetHandler(listenedEvent) %> = null;
<%
}
%>
}
The constructor script defines both variable names for the
properties and event handlers for the DOM events. The definitions render in the
constructor here; to create the correct name, the following helper methods
alter the original values as necessary.
Listing 15
public string GetHandler(string eventName)
{
return "_" + eventName.Substring(0, 1).ToLower() + eventName.Substring(1) + "Handler";
}
public string GetVariableName(string propertyName)
{
return "_" + propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
}
Any properties are defined in the list output next. If there
are no properties, the script handles this correctly and leaves an empty space.
Listing 16
<%
foreach (string property in this.Properties)
{
%>
function <%= this.GetAjaxClassName(true) %>$get_<%= property %>()
{
return <%= this.GetVariableName(property) %>;
}
function <%= this.GetAjaxClassName(true) %>$set_<%= property %>(value)
{
<%= this.GetVariableName(property) %> = value;
}
<%
}
%>
The above method renders a series of setters and getters in
the form of:
Namespace$Namespace2$get_PropertyName. You may wonder why
the "$" for the property name; this is a way to create a unique function
as the getter and setter. There are a couple of approaches to creating the AJAX interface, where this one assigns a shorter name in the prototype definition. For
instance, the property name above would have the following entry in the
prototype definition.
Listing 17
get_PropertyName : Namespace$Namespace2$get_PropertyName
The following is the rendering of the prototype.
Listing 18
<%= this.GetAjaxClassName(false) %>.prototype =
{
<%
foreach (string property in this.Properties)
{
%>
get_<%= property %> : <%= this.GetAjaxClassName(true) %>$get_<%= property %>,
set_<%= property %> : <%= this.GetAjaxClassName(true) %>$set_<%= property %>,
<%
}
foreach (string listenedEvent in this.EventsListenedTo)
{
%>
<%= listenedEvent %>Callback : <%= this.GetCallbackName(listenedEvent) %>,
<%
}
foreach (string exposedEvent in this.ExposedEvents)
{
%>
add_<%= exposedEvent %> : <%= this.GetAjaxClassName(true) %>$add_<%= exposedEvent %>,
raise_<%= exposedEvent %> : <%= this.GetAjaxClassName(true) %>$raise_<%= exposedEvent %>,
remove_<%= exposedEvent %> : <%= this.GetAjaxClassName(true) %>$remove_<%= exposedEvent %>,
<%
}
%>
initialize : <%= this.GetAjaxClassName(true) %>$initialize,
dispose : <%= this.GetAjaxClassName(true) %>$dispose
}
This simply renders the short name to long name mappings as
I mentioned above. It probably does not make a lot of sense unless you have
some ASP.NET AJAX experience, especially since I did not cover every section.