Home > .NET, Ajax, Javascript, JQuery, Vs2012 > Transform legacy js in Module Pattern

Transform legacy js in Module Pattern

2013/05/10

Tipically a lot of existing javascript code is written in the old plain mode:

function cmdAddNew_onClick() {
    showEditBox('0');
}

Every javascript programmers know that this spaghetti-code approach is hard to maintain, every function is public so it is easy to have strange behaviors that is a nightmare to debug.

The worst problems are in portals as the old Aqualogic, where was easy to have portlets with a different behavior is you inverted two portlets position in the page…

A better approach is to write our modules using a modern pattern as the Module pattern or the Singleton, there is lot a documentation about searching on Google, for examples this and this.

A skeleton of a correct Module Pattern implementation could be:

$(document).ready(function ($) {
    mycomsite.customername.projectname.context = (function ($) {
        "use strict";
        
        var cmdAddNew_onClick = function () {
            showEditBox('0');
        };      
        
        var showEditBox = function (id) {
            // js code for showing an Jquery dialog...
        }
        
        var numericSetvMax = function () {
            return '100';
        };        
        
        return {
            cmdAddNew_onClick: cmdAddNew_onClick,
            numericSetvMax: numericSetvMax            
        };
    }(jQuery));
});

The main trick is the namespace; note that we pass the jQuery variable to the module in order to use jQuery inside the module.

For example if we are a IT company with a internet site www.acme.com , we are working to a tickets solution for the scandinavian KLM company and the current is the js file for the ticketing by VISA ,a namespace could be

$(document).ready(function ($) {
    comacme.klm.ticketing.visatickets = (function ($) {
...

But we can’t have js variables with “.” in javascript, you say … the trick is a initial first module of our web app with lines as these :

if (!comacme) {
    var comacme= {};
}
comacme.klm= {};
comacme.klm.ticketing = {};

So we have defined a pseudonamespace.

Using the Microsoft Ajax Toolkit there is a better support for the namespacing , with the Toolkit we have an object named Type and we can use the method Type.registerNamespace :

<script type="text/javascript">
function pageLoad(sender, args) {
    Type.registerNamespace('comacme.klm.ticketing.visatickets');
    window.alert(Type.isNamespace(comacme.klm.ticketing)); //displays 'True'
    window.alert(Type.isNamespace(comacme.klm.ticketing.Samples.Test)); //displays 'False'
    var namespaces = Type.getRootNamespaces();
    for (var i = 0, length = namespaces.length; i < length; i++) {
        window.alert(namespaces[i].getName()); //displays 'Sys' and  other namespace components
    }
}
</script>

Ok , but we don’t use the Ajax Toolkit so let’s go back to our sample.

In the return section we indicate the public names, so cmdAddNew_onClick and numericSetvMax (functions, but also variables) are public , showEditBox is private and cannot be accessed.

That is in another javascript module we can write

comacme.klm.ticketing.visatickets.cmdAddNew_onClick();

and it works , instead

comacme.klm.ticketing.visatickets.showEditBox('0);

gives error, the internal routine is not reachable.

The variables declared correctly (with “var ” in front) remains private in the module.

This encapsulation , if well used, leads to a structure more maintainable.

Ok , but our original problem is that we could have a lot of existing js code written in the spaghetti-mode, how to convert this code to the module pattern with a minimal effort?

The Regular Expression in the Visual Studio 2012 search & replace is our tool.

We can convert an existing js file with a lot of function to the module pattern with these three couples of regexp expressions for search & replace:

^(function)
var

^(var)(.*)(\()
$1$2 = function $3

^(})(.*)
$1;$2

Open the js file (better is you separe the js code form the aspx pages…) in Visual Studio, in Search & Replace (ctrl+h) click on Regular Expression


And write the first two search%replace strings:


Note that Visual Studio 2012 gives an preview of what the search expression has found (and will be replaced):


After the three search & replace we can see something as:


The last operation is to copy the converted code in the namespace structure (below “use strict”, in practice) , inserting in the “return” part the routines names that must be public.

After, there is a tedious work of searching for the original calls (must be added the namespace part) : but this effort should resolve a lot a problems.

Advertisements
Categories: .NET, Ajax, Javascript, JQuery, Vs2012
%d bloggers like this: