Download DOWNLOAD
Forums FORUMS
Blogs BLOGS
Forge FORGE
Help HELP
Marketplace MARKETPLACE
DotNetNuke Home
You are here >   Community > Blogs
Register  |  Login

DNN Blog

Nov 12

Posted by: Jon Henning
11/12/2008 

As mentioned in Part II of this series, this entry will focus on another advantage of writing rich client side objects representing our modules on the client side.  One very common use case that comes up again and again is how can one module talk to another on the same page.  For a long time DotNetNuke had this capability from the server side through something called Inter-Module Communication (IMC).  With the adoption of AJAX it is common to hear confusion as to how can IMC work.  The question usually is asked like this.  I have Module1 talking to Module2 just fine until I "enabled AJAX" by wrapping it in an UpdatePanel.  Now Module2 no longer updates when Module1 posts back.  Or another variation is I make a ClientAPI callback that tries to either update the rendering of the module or tries to do IMC and it doesn't work.  Why not?

To understand why neither of these scenarios works the developer needs to have a basic understanding of what is happening behind the scenes.  An AJAX call into some server-side code should never be about sending a request from the client and have the entire page refresh.  If this is the requirement, then just use a normal postback!  Instead, AJAX calls are about requesting some piece of data (data here could be anything including HTML) that in turn affects the client-side state in some way, usually resulting in some UI update.  One of the primary motivations of using AJAX is to make a more responsive and efficient web experience.  So it makes sense that the AJAX you are adding should be written in such a way to minimize the strain on the server along with the bandwidth of the network. 

The idea behind the UpdatePanel is to allow only a portion of the page to be posted to the server, have less processing on the server happen than a normal postback, and only send down the updated portions of the page.  This is better than the postback, but not as good as it could be.  For the scenario where a user needs to do some sort of IMC, the UpdatePanel gets rather tricky real quick due to the need for triggers.

The approach I am pushing is to simply have the module become aware of the other modules it may wish to communicate with on the client.  Once aware, the module can simply interact with the other module's client-side object model, invoking methods and properties as needed.  I mentioned in Part I of this series that there was an important difference between the initialize and load events.  The load event will fire after all client-side objects have been initialized.  This offers an ideal place for our modules to become aware of each other.

    _onLoad: function(src, arg)
    {
        //page is completely loaded, you can now access any element or component
        var components = arg.get_components();
        //sample of how to do client-side IMC - look for other components we are interested in
        //in this case, we will look for other instances of the same module that are not ourselves
        //but you can communicate with any components
        for (var i=0; i<components.length; i++)
        {
            if (Object.getTypeName(components[i]) == Object.getTypeName(this) && components[i].get_id() != this.get_id())
                this.add_propertyChanged(components[i]._delegates.componentPropChangedDelegate);
        }
    },

An additional bonus to this event is the arg parameter contains a list of components for us via the get_components property.  We simply need to enumerate the list of components looking for an object of the same type that is not ourself and add an event handler to it.  Obviously, this logic can be tweaked to look for any type of component.  The propertyChanged event is another feature that the Sys.Component offers.  Whenever we wish to notify other objects of some property changing we simply call raisePropertyChanged.  In our module's case we will raise the SayHello property changed event when we click a button

        this.raisePropertyChanged('SayHello');

This event will get trapped by other instances and update the UI accordingly

    _onPropChanged: function(src, args)
    {
         this.showMessage(String.format('You {0} to {1} but not to me?', args.get_propertyName(), src.get_name()));
    },

Notice how we get both the source object that raised the event, along with the propertyName that raised the event.  Obviously this allows for a single event handler to service many different property changed events.  Additionally, it allows for easy interaction with the calling object.  This is effectively all you should need to get your modules talking.  Obviously, each module you talk to could do whatever logic you'd like, including making AJAX calls and updating UI. 

This concludes the mini-series of blog entries on Microsoft AJAX and the ClientAPI.  Hopefully it gives the reader enough information to go and create a new breed of module, one that fits better into the AJAX era.

 

For those interested in my upcoming plans I wanted to mention that I will soon be updating the free module templates found on codeplex which will generate nearly all that has been covered in this series.  Until then, I figured I'd let anyone who is interested play with the package the template creates:  Install or Source.  Note:  This module requires DNN5.  I haven't gotten around to updating the manifest yet, that will be done by the time I release the template.  Enjoy!

Tags:

3 comment(s) so far...

Re: Utilizing the Microsoft AJAX Framework and ClientAPI to Develop Rich Modules: Part III

Very good. Is there a way this can be implemented in DNN 4.5x also?

By fj reinders on   11/20/2008

Re: Utilizing the Microsoft AJAX Framework and ClientAPI to Develop Rich Modules: Part III

This can be done in DNN4.5 if the clientapi and webcontrols dlls and scripts are moved to it AND the Microsoft AJAX Framework is installed.

By Jon Henning on   11/20/2008

Re: Utilizing the Microsoft AJAX Framework and ClientAPI to Develop Rich Modules: Part III

Vicenc, this line obtains a collection of the client-side components that are registered with MSAJAX. This allows us to easily listen for who else is on the page that we may wish to interact with (a kind of client-side IMC). Perhaps the original video covering the code from the 1.0 template would help as I spend a lot more time going into the details of each line of code. (blip.tv/file/get/Codeendeavors-ProgrammingWithTheCodeEndeavorsAJAXModuleTemplate676.wmv). Specifically, this topic is covered at the 24:30 mark.

By Jon Henning on   12/9/2008

Networks

Follow DNNCorp on Twitter

LinkedIn

Follow us on Twitter @DNNCorp or join the DotNetNuke Community on LinkedIn

Sponsors

DotNetNuke®, DNN®, and the DotNetNuke logo are trademarks of DotNetNuke Corporation

Hosted by MaximumASP