Saturday, September 15, 2007 4:47 PM codeblock

A Javascript class for pages... that is to say: how to better organize the scripts

This post is my english translation of the italian version I posted some days ago. Hoping it may be better than the automated Italian to English translation from google. I have not merely translates word-by-word the previous post but I have completely rewritten the post.

Whoever had ever written web applications know that scripting code has the disagreeable habit to make the markup plenty of code and cross references that make page hard to read and maintain. So, i decided to write this post explainig the way I recently adopted to strip out the biggest part of this scripting code infesting my pages. So here is the title of this post, that wants to teach a better way to organize our scripting code by creating a

I had this idea working with Microsoft AJAX Library, I tried to implement it during my working time, end it become my only way to work because it permit to separate interface from logic as many code guru explains from many years. The base of this idea is a little class, written using the library that I use as base class for every page I make.

1 Type.registerNamespace('Elite'); 2 3 Elite.Page = function() 4 { 5 this.onload$delegate = Function.createDelegate( 6 this, 7 function(eventData) 8 { this.load(); }); 9 10 this.onunload$delegate = Function.createDelegate( 11 this, 12 function(eventData) 13 { this.unload(); }); 14 15 window.onload = this.onload$delegate; 16 window.onunload = this.onunload$delegate; 17 18 Elite.Page.initializeBase(this, [window]); 19 } 20 21 Elite.Page.prototype = 22 { 23 initialize : function() 24 { 25 Elite.Page.callBaseMethod(this, 'initialize'); 26 }, 27 load : function() 28 { }, 29 unload : function() 30 { }, 31 dispose : function() 32 { 33 if (this.onload$delegate) delete this.onload$delegate; 34 if (this.onunload$delegate) delete this.onunload$delegate; 35 36 Elite.Page.callBaseMethod(this, 'dispose'); 37 } 38 } 39 } 40 41 Elite.Page.registerClass('Elite.Page', Sys.UI.Control);

This class do some simply things I will use every time I devolp a page and grant me the capability to approach the web page development every time in the same way, in a similar way like when i write an ASP.NET codebehind page. The class attachs the onload and onunload events and define also a load() and unload() method called every time this events happen. So like a common ASP.NET page it will have initialize, load, unload and an addictional dispose method useful for deallocating resources like event handler that waste of memory leaks the browsers. When we will write the page class it will b really important to call the bae method every time we override oneof these methods.

Here is how to work with this class when creating a page:

1) first of all we have to create a codebehind file ina a way similar to visual studio behavior. Giving a page called dashboard.aspx I will create a javascript codebehind called dashboard.aspx.js. I simply put this file side by side with the page because when I deploy the application tipically I make this scripts embedded resources and will load them using webresource.axd directly frm the web application assembly (giving you use web application project). This file will contains a class extending my Elite.Page class.

2) now it is the time to include the javascript file with the "Elite.Page" class definition (I call it page.js). It is rquired also you include the Microsoft AJAX Library so if you are developing an ASP.NET page probably the better things todo is to reference this file into the ScriptManager <scripts> collection.

3) after setting up the files in the directory, it is now tim to implements the class specific for our page. I will name it always with the same name I use for the C# codebehind class. Here is a sample:

1 Type.registerNamespace('MyApplication'); 2 3 MyApplication.DashboardPage = function() 4 { 5 MyApplication.DashboardPage.initializeBase(this, [window]); 6 } 7 MyApplication.DashboardPage.prototype = 8 { 9 load : function() 10 { 11 this.bSave = $get('bSave'); 12 MyApplication.DashboardPage.callBaseMethod(this, 'load'); 13 } 14 }; 15 16 MyApplication.DashboardPage.registerClass('MyApplication.DashboardPage', Elite.Page);

In this sample you may see the right place how to "register" controls you will use later in the page lifetime. As you may see in the load() event handler I search for a control named "bSave" and record it into a variable with the same name. Here I can also attach event handlers (e.g. the onclick button) to handler user inputs. To take a rference you will use $get()

4) To reference the class, you have to push a little script into the startup sequence. I usually use the ScritpManager.RegisterStartupScript() to insert this simple line:

var currentPage = $create(MyApplication.DashboardPage, {}, {}, null, null);

Calling this method you simply take an instance of the class. It will also call the initialize method starting the page lifecycle. You may manage events during this cycle in the same way you do with ASP.NET pages. There was only a little trouble. All you know that ASP.NET pages create a composite id for WebControls. So to take references to this objects you will have to pass this id from the ASP.NET server-side code to the client-side javascript class using the ClientID property. I have a small idea incubating... but this will be argument for a future post.

Filed under: , ,

Comments

# re: A Javascript class for pages... that is to say: how to better organize the scripts

Saturday, September 15, 2007 12:00 PM by garbin

Hi,

thanks for sharing your code Andrea. Here are my comments:

1. The Microsoft Ajax Library already provides a component that manages the client lifecycle of a web page. It is Sys.Application. It raises load and unload events just as your control does. It also lets you declare two functions called pageLoad and pageUnload, which will be automatically called during the load and unload stages.

2. I see you're registering the class as a control. Actually, controls are supposed to provide a specific user interface. A component would be better suited for this kind of tasks. If you need a singleton, you could check how a similarpattern is implemented by Sys.Application.

3. You're attaching handlers to window.load and window.unload events. This isn't the safest way to deal with the Microsoft Ajax Library, since the runtime might not be initialized when window.load is raised. The safest way is to handle the load and unload events raised by Sys.Application.

4. If you design a client component that manages the lifecycle of a webpage, it should theoretically be the

component with the longest lifespan. Instead, since you're using $create, it will get disposed by Sys.Application before the page is unloaded by the browser. In fact, Sys.Application is the client component with the longest lifetime (that is one reason why it was called Sys.Application and not Sys.Page).

5. To make things clearer, nothing prevents you from creating an alias for Sys.Application in the following way (after creating the necessary namespaces):

var MyApplication.DashboardPage = Sys.Application;

# re: A Javascript class for pages... that is to say: how to better organize the scripts

Saturday, September 15, 2007 4:33 PM by codeblock

hi,

many thanks for your appreciated feedback about my tecnique. I agree with you that Sys.Application is a valuable friend, but I think it may be useful in collaboration with the Page class and not in sobstitution. Remember that the purpose of my example is to encapsulate all the page lifecycle in a single class, similar to asp.net server-side behavior. In this way you may include all the event handling and interface logic into this class instead of disperse it in multiple functions mixed with the page markup. I agree that probably it is better to use Sys.Application methods to handle load and unload events. I choice to inherit from Sys.UI.Control instead of from Sys.Component because this class have to represent a real control with a specific interface(the page). I really do not want to create an alias to Sys.Application... again, I need to encapsulate all page logic.

# Link Listing - September 17, 2007

Tuesday, September 18, 2007 4:07 AM by Christopher Steen

Link Listing - September 17, 2007

# 13 Links Today (2007-09-20)

Thursday, September 20, 2007 11:23 AM by 13 Links Today (2007-09-20)

Pingback from  13 Links Today (2007-09-20)

# javascript onunload delete file

Saturday, May 10, 2008 2:26 PM by javascript onunload delete file

Pingback from  javascript onunload delete file

Leave a Comment

(required) 
(required) 
(optional)
(required)