Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suggestions for namespace setup for website, and page specific object's etc

I want to create a namespace or global object that will hold site wide used functions etc.

Also, on specific pages, I want to create a object that will hold state based on the current page and if the user is logged in, if so, then I will pull state information based on the current user.

What is the suggest pattern for this?

like image 849
Blankman Avatar asked Feb 24 '23 11:02

Blankman


2 Answers

JavaScript does not have namespaces. However, when most of us refer to namespaces in the context of JavaScript, what we really mean is storing our functions and data in objects in a modular fashion without cluttering up the global context.

There are a several libraries that handle dependency management and script loading, but I'm not going to cover any of that right now:

To create a namespace, you must first create an object in the global context.

Creating a namespace:

At its most basic level, this is as easy as:

window["MyOrg"] = {};

Typically, your base object won't have any data or functions but will rather be composed of submodules. The most basic form for creating submodules is practically the same:

MyOrg.submodule = {}

You can extend this pattern to any level you want. e.g. MyOrg.submodule.tools.usefulFunction


Note: If you are defining your modules and sub modules in different files that may be loaded in any arbitrary order, you must first check to see if your namespace (and any parent modules) exists so 1) you don't get an error when defining your module and 2) so you don't overwrite any modules, but augment them.

For example, if you're defining the MyOrg.submodule module, you would need to include:

var MyOrg = MyOrg || {};
MyOrg.submodule = MyOrg.submodule || {};

Now that you have your submodule setup, you can easily assign members to it using the expected notation:

MyOrg.submodule.add = function (x, y) {
   return x + y;
}

MyOrg.submodule.CONSTANT = 42;

If you can guarantee that you are defining the sub module for the very first time (no risk of overwriting anything), you can also use:

MyOrg.submodule = {
   add: function (x, y) {
      return x + y;
   },
   CONSTANT: 42
};

"Advanced" methods

Ok, you should about get the gist of it. However, there are slightly more advanced patterns that you can follow, particularly the "Module Pattern:"

MyOrg = MyOrg || {};
MyOrg.submodule = (function () {
    /* any variables (incl. functions) in here are effectively private -- they 
       cannot be accessed or modified unless they are explicitly exposed. */
    var privateVariable = 42; 

    /* We return an object that will define the public API. Functions defined 
       in this object still have access to our "private" scope */
    return {
       getVar: function () {
          return privateVariable;
       },
       setVar: function (value) {
          privateVariable = value;
       }
    };
})();

You use your modules using the same exact notation, but with the added benefit of having private variables and functions:

MyOrg.submodule.setVar(2);
MyOrg.submodule.getVar(); // 2

Regarding your second question, there are a few ways you could do that.

First, you could add generate the javascript on the server side with the relevant data already baked in.

var MyOrg = MyOrg || {};
MyOrg.userInfo = {
   userName: "<%= @user.user_name %>",
   location: "<%= @user.location %>"
   //etc.
}

You can also fetch it from the server from the client-side using AJAX and JSON

$.ajax({
   url: "user/getInfo", 
   success: function (data) {
      // data is an object created from a JSON string containing info for the
      // current user, presumably using session data.

      alert(data.userName)
   }
});

If you use this method you may have to use callbacks in your user module to get the relevant info, or you can implement caching methods (with the added benefit of not creating so many server requests).

like image 149
Cristian Sanchez Avatar answered Apr 28 '23 06:04

Cristian Sanchez


You can probably declare a base javascript file called base.js and define various namesspaces as below

base namespace

yourcompany.Projectname = {};
yourcompany.Projectname.modules = {};
yourcompany.Projectname.components = {};

and then in each javascript files , you can create functions with the above namespace

like image 25
kobe Avatar answered Apr 28 '23 06:04

kobe