I am trying to figure out how to start off some structure for a new page.
The page is called ‘Orders’ and it will have a couple of tabs on it for now: ‘OrdersTab’ and ‘TasksTab’
I’ve got my layout setup like so:
//Namespace for the 'Orders' page.
var Orders = (function () {
"use strict";
var tabs = $('#OrdersTabs').tabs();
var ordersTab = new OrdersTab();
var tasksTab = new TasksTab();
//Public methods:
return {
};
})(); //Load when ready.
My intention here is to have the Orders namespace be in charge of loading the tabs. I am struggling with understanding how to keep my OrdersTab and TasksTab in the same ‘namespace’ as Orders. Ideally, another page would not be able to instantiate an OrdersTab.
//Namespace for the 'OrdersTab' from the 'Orders' page.
function OrdersTab() {
"use strict";
var ordersGrid = $('#OrdersGrid');
var ordersGridPager = $('#OrdersGridPager');
ordersGrid.jqGrid({
url: '../Orders/GetOrders/',
datatype: 'json',
colNames: ['Name', 'Description'],
colModel: [
{ name: 'Name', index: 'Name', sortable: false, width: 150 },
{ name: 'Description', index: 'Description', sortable: false, width: 300 }
],
gridview: true,
height: 'auto',
rowNum: 10,
pager: ordersGridPager,
viewrecords: true
});
//Public methods:
return {
};
};
Orders is located in Orders.js and OrdersTab is located in OrdersTab.js. It seems to me that a new OrdersTab could ‘accidentally’ be created by someone else, or the function name made ambiguous accidentally. Is it possible to wrap up OrdersTab inside of the Orders ‘namespace’ while also keeping it in a separate file? I think separate files are necessary in case each tab grows larger than expected / allow for the introduction of additional tabs in the future.
Furthermore, I was wondering if it was possible to use the same setup structure between both files. It seems awkward to me that I assign to a variable for Orders, but just create a function with OrdersTab. Maybe that is OK and standard, though, I just would like to know.
There are several solutions, ranging everywhere from putting everything inside of that one function, which you don’t want to do, down to completely sandboxing every module, and giving them a messaging system to communicate with one another (similar to how MacOS runs).
A happy medium would be to build a loading-system into your primary application:
Feel free to build in a promise system, or a mediator system. With these, you can fire off custom events, internal to your application, to handle dependencies and initialization, and all of the rest.
Then you’ll have the ability in other files to do something like:
So in your actual document, you just need to use
APPNAME.load("modulename");to load “modulename.js”, which will then be accessible asAPPNAME.publicNameas whatever you decide it to be.And again, you can further abstract that… …you could have an
addPublicand anaddPrivatefor services or for modules. You could store your modules inside of a hidden object, instead of on the public object, you can use theimplementationas a constructor, or as another IIFE to return another object.In advanced sandboxes, you’d probably load these into a
modulesobject, and then when you initialize each module, you could pass its initialize function an object which has access to, say your JS Library (jQuery/Dojo), and the application’s messaging system.In order to be really sandboxed, that system-object would only be an instance, rather than a shared object, so that tampering with it would only seal that module off, rather than messing with anything else in the system.
…of course, by this time, you’re really, really involved, and this could relatively-securely scale a large application.
I’m not saying you should go that far overboard. What I am saying is that there’s always more, and things can always be abstracted further, to accomplish what you need to.
I like that about JS.