【问题标题】:Javascript namespaces and conditional inclusionJavascript 命名空间和条件包含
【发布时间】:2011-11-03 20:02:39
【问题描述】:

我有一些以这种方式组织的 js 文件(请参阅source):

  • gmaps4rails.base.js:包含所有逻辑

    • gmaps4rails.googlemaps.js:包含函数

    • gmaps4rails.bing.js:包含与上一个文件同名的函数

所以基本上,base 调用 createMarkers(),这在 googlemapsbing 中。

从现在开始,我只加载gmaps4rails.googlemaps.jsgmaps4rails.googlemaps.js 中的一个,这取决于我需要的地图API,所以它工作正常。

现在我希望能够加载所有文件(并将它们分开),但当然只包含所需地图 API 的代码。

基本上我会考虑这样的事情:

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

提前致谢。

【问题讨论】:

  • 您是否尝试为createMarkers() 函数实现策略模式?
  • 这些函数是全局的吗?如果是,那就是问题所在。您不希望有一个包含一堆污染全局命名空间的全局函数的脚本 - 相反,对于您想要定义 one 全局名称(命名空间)的每个脚本,然后将所有内容(那些函数)在那个命名空间内。如果您这样做,您将能够轻松地包含(和使用)这两个脚本......
  • @whatgoodisaroad:我对js不够熟悉回答这个问题,我去看看定义
  • @Šime Vidas:我确实有两个命名空间 BaseGoogleMaps 我如何将一个合并到另一个?
  • @apneadiving 这不是真正的 JS 术语,策略模式是通用的 design pattern。基本上,它允许你通过一个统一的接口调用任意数量的实现。

标签: javascript ruby-on-rails


【解决方案1】:

如果我理解正确,您只是希望能够根据用户选择(或其他一些标准)使用 google maps API 或 bing API 或其他 API?为此,与其尝试将正确的 API 合并到您的基础对象中,不如直接从基础对象中引用“mapService”并根据您想要的条件选择 mapService?

类似这样的:

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();
});

这是你想做的吗?

希望对你有帮助

【讨论】:

  • 我最终做了基本的继承(如果你好奇,我的源代码会更新)。不管怎样,你的方法也适合!
【解决方案2】:

我认为您正在寻找某种异步加载器。 CommonJS 提出了 Modules 1.1Asynchronous Module Definition (AMD) API 来做这件事。有很多异步加载器的实现,如this Google spreadsheet 中所列。其中,有一些符合 AMD 标准,例如:

blog entry 对此话题进行了很好的讨论。

另请参阅此 SO 帖子:Namespace a dynamically loaded javascript file's contents

【讨论】:

  • 感谢您提供这些资源和 +1。它们具有很大的附加值。我终于做了基本的继承(如果你好奇,源代码更新)。
猜你喜欢
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 2019-06-20
  • 2014-09-06
  • 2011-07-24
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
相关资源
最近更新 更多