I'm building a MVC web app with heavy use of ajax loaded partial views containing jQGrids and javascripts. Many of the partial views contains only 2 div tags and the rest is javascripts.
Using script tags makes the general page structure much more logic to me, because the javascripts are the content of the page as I see it.
However there are also small utilityfunctions, like formatting functions, used by jQGrid and I'm starting to see an increasing risk of scripts with the same name performing almost identical tasks.
Example of formatting function:
function primaryRoleFormatter(cellvalue, options, rowObject) {
switch (cellvalue) {
case "1":
return "<%= Resource.PRIMARY %>";
default:
break;
}
return "";
};
At first I saw the formatting functions as belonging to the closest grid, especially since there might be other grids having a formatting function with the same name but with some small differences in the code.
I load two or more grids at the same time, it seems that javascript is smart enough to use the script defined in the current script block if there's a name clash so there's no problem yet beyond the nagging thoughs, "is this the best way of doing this?".
There's also scripts for ajax-loading and displaying jQuery dialogs from grid actions. I'm thinking that the scripts will add up over time.
Should I just keep the scripts where they are used or should I try to build a script library of some kind?
If I should move them out to script files, what's a smart way of partitioning the functions (names, classes, files...)? If I move them out, would they be considered more unobtrusive as this type of page is already loaded by ajax itself and consisting to 95% of javascripts?
I realize there are similar questions but I didn't find any suiting answer. If there's a problem with this, I'll delete it.
The simplest way to avoid unnecessary pollution of the global namespace is to place related functions in an object literal:
var Formatter = {
primaryRoleFormatter: function(cellvalue, options, rowObject) {
switch (cellvalue) {
case "1":
return "<%= Resource.PRIMARY %>";
default:
break;
}
return "";
},
someOtherFormatter: function() {
}
}
Which can then be used like this:
Formatter.primaryRoleFormatter(cellvalue, options, rowObject);
Formatter.someOtherFormatter();
This results in one property on the global object instead of one for each function you define.
Or you could hide things with function scope:
var Formatter = (function() {
function FormatterCtor() {
// instance-ish level func
this.onePerInstance = function() {}
}
// not accessible from the outside; not in the global namespace
function privateFunction() {}
// class-ish level func
FormatterCtor.oneShared = function() {}
return FormatterCtor;
})(); // self-executing
Which can be used like this:
var fmt = new Formatter();
fmt.onePerInstance();
In either case, you end up with just one variable in the global namespace, which is a win.