Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript namespaces and conditional inclusion

I've some js files organized this way (see source):

  • gmaps4rails.base.js : contains all the logic

    • gmaps4rails.googlemaps.js : contains functions

    • gmaps4rails.bing.js : contains functions with the same name as the previous file

So basically, base calls createMarkers() which is in both googlemaps and bing.

From now, I load only one among gmaps4rails.googlemaps.js and gmaps4rails.googlemaps.js, depending on the map API I need, so it works fine.

Now I'd like to be able to have all files loaded (and keep them separate) BUT of course only include the code of the desired maps API.

Basically I think about something like:

if desiredApi == "googlemaps"
   include GoogleMapsNameSpace content in BaseNameSpace

Thanks in advance.

like image 224
apneadiving Avatar asked Aug 25 '11 15:08

apneadiving


2 Answers

If I understand correctly you just want to be able to use either the google maps API or the bing API or someother based on the user selection (or some other criteria)? For that, instead of trying to merge the correct API into your base object, why don't you just refer a 'mapService' from your base object and select the mapService based on the criteria you want?

Something like this:

Map = function(service, canvasId) {
    var mapService = MapServices[service];

    return {
        initialize: function() {
            var theMap = mapService.createMap();
            mapService.render(canvasId);
        }
// more functionality for your base object (that the outside world calls) goes here

    }
}

var MapServices = MapServices || {};

MapServices.google = {
  createMap: function() {},
  render: function(canvas) {
    $("#"+canvas).html("I'm a google map");
  },
  createMarker: function(args) {}
// all your map functionality goes here calling google specific functions
};

// this could be in a different js
MapServices.bing = {
  createMap: function() {},
  render: function(canvas) {
    $("#"+canvas).html("I'm a bing map");
  }, 
  createMarker: function(args) {},
// all your map functionality goes here calling bing specific functions
}

$(function() {
  var theMap = new Map("google", "theDiv");
  theMap.initialize();
});

Is this what you want to do?

Hope this helps

like image 103
Jaime Avatar answered Sep 21 '22 17:09

Jaime


I think you are looking for some kind of asynchronous loader. CommonJS has proposed Modules 1.1 and the Asynchronous Module Definition (AMD) API that do this. There are quite a few implementations of async loaders, as listed in this Google spreadsheet. Of which, a few of them are AMD-compliant, for example:

  • curl.js http://github.com/unscriptable/curl
  • RequireJS http://requirejs.org/
  • bdLoad http://bdframework.org/bdLoad

This blog entry has a nice discussion on this topic.

Also see this SO post: Namespace a dynamically loaded javascript file's contents

like image 45
William Niu Avatar answered Sep 23 '22 17:09

William Niu