Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

Microsoft Ajax events - part 1: subscribing

When building Ajax applications, you basically deal with two kinds of events. First, there are DOM events, and second, events from JavaScript objects. This second category is not part of the EcmaScript specs (or of the DOM specs, of course) so each framework needs to define its own pattern to expose events. This makes it more difficult for developers to include components built on different frameworks into a single page, which is one of the problems that OpenAjax tries to solve. I'll get back to this in a future post and show how to integrate Microsoft Ajax events in the OpenAjax hub.

As with other parts of the Microsoft Ajax framework, we've tried to adhere to the .NET patterns as much as possible when we designed events in Microsoft Ajax. Events are defined by their "add" and "remove" accessors, which respectively add and remove handlers. For instance, PageRequestManager exposes a "beginRequest" event by exposing the "add_beginRequest" and "remove_beginRequest" methods. Both add and remove accessors have the same signature, which is that they take a single "handler" parameter of type Function.

So handling an event is twofold. First, you must subscribe to an event, which is as simple as the following highlighted code:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> <script type="text/javascript"> function pageLoad() { var prm = Sys.WebForms.PageRequestManager.getInstance(); if (!prm.get_isInAsyncPostBack()) { prm.add_beginRequest(onBeginRequest); } } function pageUnload() { Sys.WebForms.PageRequestManager.getInstance()
.remove_beginRequest(onBeginRequest); } function onBeginRequest(sender, args) { Sys.Debug.trace(args.get_postBackElement().value +
" triggered a postback."); } </script> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager runat="server" ID="SM1"></asp:ScriptManager> <asp:UpdatePanel runat="server" ID="UP1"> <ContentTemplate> <asp:Button runat="server" ID="Button1" Text="Button 1" /> <asp:Button runat="server" ID="Button2" Text="Button 2" /> <asp:Button runat="server" ID="Button3" Text="Button 3" /> </ContentTemplate> </asp:UpdatePanel> <textarea id="TraceConsole" cols="40" rows="15"></textarea> </div> </form> </body> </html>

This page starts by subscribing to the beginRequest event of the page request manager. The handler for the event which is passed to add_beginRequest, onBeginRequest, looks at the event arguments and displays the value of the button that triggered the postback in the trace console. This brings us to the second half of using events, writing the handler. All Microsoft Ajax event handlers, by convention, and exactly like in .NET, have a similar signature: they take two parameters, the event sender and the event arguments. The sender is the object that raised the event (in the example above, that would be the PageRequestManager) and the arguments are an instance of a type that derives from Sys.EventArgs. Many events will be associated with a specific argument class to enable the handler to get additional and specific information about the event. In the example above, we're using the postBackElement property of the arguments, which are of type Sys.WebForms.BeginRequestEventArgs. Similarly, the propertyChanged event on Sys.Component is associated with Sys.PropertyChangedEventArgs, which exposes a propertyName property that enables the handler to determine the name of the property that triggered the event. In other words, to learn how to properly handle an event, start by exploring its associated arguments class.

In the next post, I'll show how to expose a custom event from your own classes:
http://weblogs.asp.net/bleroy/archive/2007/05/22/microsoft-ajax-events-part-2-exposing-events-from-custom-classes.aspx

Comments

Ron said:

Bertrand, How is the event subscription model implemented internally? Is it done using closures? Thanks.
# May 17, 2007 9:59 AM

Ryan Williams said:

I didn't realize that you can use a pageLoad() and pageUnload() handler that is automatically called by the framework. Neat.
# May 17, 2007 8:33 PM

Bertrand Le Roy said:

Ron: not sure what you mean. Can you be more specific?

# May 18, 2007 12:45 AM

Jesse said:

This is great stuff! Keep it coming! I was wondering if I could use this with an end handler to change the size of divs on a page after the event fired. I am having some issues in firefox with sizing divs with all this dynamic changing going on. If you have an example of this I would really appreciate it! I have been trying to get it to work but with no success thus far
# May 22, 2007 6:03 PM