This article is based on Chapter 3 of ASP.NET in Action by Alessandro Gallo, David Barkol, and Rama Krishna Vavilala, published by Manning Publications, September 2007. For more information, visit
http://www.manning.com/gallo
JavaScript developers are acquainted with the event model provided by the DOM. You can program against the DOM elements of a web page by hooking up their events and executing code in event handlers. For example, a button element can raise a click event when it's clicked by the user. The window object raises a load event when the page is loaded and an unload event when the user navigates away from the page.
Although DOM objects can raise events, this isn't true for generic JavaScript objects. The Microsoft Ajax Library provides an event model that lets you expose events in client objects, following a model that closely resembles the one used in the .NET framework. We'll divide this discussion into two parts. First, you'll see how to expose an event in a JavaScript object. Then, you'll learn how to subscribe to and handle an event.
Exposing an Event
With the Microsoft Ajax Library, you can expose an event in a JavaScript object and subscribe to it with multiple handlers. This means that events are multicast, because you're able to handle them with multiple functions. Exposing an event is a three-step process:
- Create a method that adds an event handler.
- Create a method that removes an event handler.
- Create a method that is responsible for raising the event.
The methods responsible for adding and removing the event handlers must follow a naming convention defined by the Microsoft Ajax Library:
- The name of the method responsible for adding an event handler must be called
add_eventName, where eventName is the name of the event.
- The name of the method responsible for removing an event handler must be called
remove_eventName, where eventName is the name of the event.
For example, if the object exposes an event called initialize, it has two methods called add_initialize and remove_initialize. These methods are responsible for adding and removing event handlers for the initialize event. The Application object, which we introduced in chapter 2, exposes some events, one of which is init. The Sys.Application object has two methods called add_init and remove_init.
Note: In the .NET framework, the process for exposing events is conceptually similar. There, we use a delegate to add and remove event handlers, and we fire the event by executing the delegate. A good article about the .NET event model can be found at
http://msdn.microsoft.com/msdnmag/issues/03/02/BasicInstincts/
Figure 1 illustrates the pattern used in the Microsoft Ajax Library to expose an event in a JavaScript object.
Figure 1: With the Microsoft Ajax Library, objects can expose events. The add_eventName and remove_eventName methods (where eventName is the name of the event) are used to add and remove an event hander, respectively. Internally, a function called _raiseEvent can be used to raise the event.

In order to be able to manage multiple event handlers, the Microsoft Ajax Library provides a class called Sys.EventHandlerList, which encapsulates an object used to store multiple event handlers for multiple events. You access this through two class methods: addHandler and removeHandler. Objects that want to expose events usually create an instance of the class in the constructor and store it in a private property:
At this point, the event methods interact with the event handlers list in order to manage event handlers.
Note: The base Sys.Component class, used for creating client components, already comes with an instance of the Sys.EventHandlerList class and support for client events. Client components are discussed in chapter 8.
Listing 1 puts the theory into practice and shows how this is done in a Collection class that wraps an array. The class can raise an itemAdded event whenever a new element is added to the array. For simplicity, we show only the code for the add operation, but removing an element can be implemented with similar code.
Listing 1: A Collection class that wraps an array
The add_itemAdded and remove_itemAdded methods are responsible for adding and removing event handlers for the itemAdded event. They interact with the event-handlers list by invoking its addHandler and removeHandler methods. In the code, the list of event handlers is accessed through a method called get_event, which returns the instance stored in the _events field. Note that the creation of the Sys.EventHandlerList instance is done (lazily) only the first time the object tries to access the events property, so that constructing an instance doesn't cost the creation of the event list if it's not going to be used. This is done to remain consistent with the model used by client components, which encapsulate an instance of the Sys.EventHandlerList class by default. More information is given in chapter 8, which is entirely dedicated to client components.
Instead of writing a separate method to fire each event you're exposing, it's preferable to write a single _raiseEvent method and pass it a string with the event name and the event arguments. The _raiseEvent method calls getHandler on the event-handlers list to retrieve all the handlers for the given event. Stored in the handler variable is a function that, when called, executes all the handlers for the event.
When the handlers are called, each of them receives two arguments: a reference to the object that raised the event and an object that contains the event arguments. This paradigm should be familiar to .NET developers, because in the .NET framework, event handlers receive similar arguments. Note that if you don't specify any event arguments, the _raiseEvent method uses Sys.EventArgs.Empty, which is the static, singleton instance of the Sys.EventArgs class. This instance represents the absence of event arguments.
In the add method, we are explicitly passing the Sys.EventArgs.Empty instance when calling _raiseEvent to fire the itemAdded event. A full implementation would probably derive a custom class from Sys.EventArgs that includes a reference to the item that was just added.
Now that we know how to expose an event, let's see how external objects can subscribe and handle it.
Subscribing and Handling Events
In the previous section, we discussed how to expose an event in a client object. Now to this question: How can you subscribe to and handle such an event? Subscribing to an event is simple: All you have to do is call the method responsible for adding an event handler.
For example, if you want to subscribe to the itemAdded event raised by the Collection class defined in listing 3.16, you pass a JavaScript function to the add_itemAdded method of the Collection instance. This function is an event handler for the itemAdded event. If you pass the same function to the remove_itemAdded method, you remove it from the list of event handlers. To add multiple handlers, you have to invoke the add_itemAdded method multiple times. Translated into code, event subscription is performed as follows:
Now, you need to define the onItemAdded function, which is the event handler that you passed to the add_itemAdded method. You can do so this way:
The event handler is a function that accepts two arguments. We called these arguments sender and e to emphasize the similarity with the event model used in the .NET framework. Finally, we add an item to the collection in order to fire the itemAdded event. This is done in the following way:
As we explained in the previous section, the event handler receives references to the object that raised the event and an object that represents the event arguments.
Listing 2 shows the complete sample code needed to test the new itemAdded event.
Listing 2: Sample code to test the itemAdded event
Summary
We've discussed how you can expose multicast events in JavaScript objects using the event model provided by the Microsoft Ajax Library, which closely resembles the one used in the .NET framework.
About Alessandro Gallo
 |
Alessandro "Garbin" Gallo is a Microsoft MVP in the Visual ASP/ASP.NET category and a .NET developer/consultant. He is a contributor for the Ajax Control Toolkit project, owned by Microsoft. Alessandro won the Grand Prize at the "Mash-it-up with ASP.NET AJAX" contest held by Micr...
This author has published 23 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
DevReach Follow-up, Part I
read more
Ajax.NET Professional and ASP.NET MVC
read more
ASP.NET Data Control Events
read more
AJAX >> Using AJAX to load a usercontrol that has refers to a custom css file
read more
Asp.net MVC more Form post scenarios and Ajax
read more
ASP.NET Memory Issues
read more
WebUI Studio.NET 2008 R1 SP2 is now available
read more
How to set up a web project using the AjaxEngine Part 1b
read more
How to setup a new AjaxEngine web project
read more
Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Performing Client Actions in Response to Partial Page Postbacks
read more
|
|
Please login to rate or to leave a comment.