1

假设您有一个使用第 3 方 JS API(使用 dojo)的用户控件。您有一个 JS 函数loadMap,它为您的控件初始化一些全局变量并将一些事件(来自 3rd 方 API)连接到您的 JS 事件处理程序。在您的事件处理程序中,您需要使用您在loadMap.

问题: 如果我在同一页面中有多个此控件的实例,则全局变量将相互覆盖并且不起作用。

问题:如果有意义的话,
我如何编写 JS 以在控件实例的范围内拥有全局变量?或任何可以解决我的问题的建议。

这是我的控制 JS 代码(我将其最小化以显示问题),我的全局变量在前 3 行中定义

//create the global variables
var mapVar;
var geocoderVar;
var toolbarVar;

function loadMap(divMap, divSearch) {
    ...
    // create the map 
    mapVar = new esri.Map(divMap, {
        zoom: 0,
        minZoom: 0,
        maxZoom: 10,
        lods: lods
    });     

    // create the geocoder 
    if (geocoderVar === null) {
        geocoderVar = new esri.dijit.Geocoder({
            map: mapVar
        }, divSearch);
        geocoderVar.startup();
    }
     //Hook up event handlers
    dojo.connect(mapVar, "onExtentChange", checkScale);
    dojo.connect(mapVar, "onLoad", createToolbar);       
}

function createToolbar(themap) {
    dojo.connect(mapVar, "onClick", function (evt) {
        if (canDrop === true) {
                point = evt.mapPoint;
            mapVar.graphics.clear();
           ...
        }
        ...

    });
     //create the toolbar variable
    toolbarVar = new esri.toolbars.Draw(mapVar);
    ...
    dojo.connect(toolbarVar, "onDrawEnd", addToMap);
}

 function checkScale(extent, delta, outLevelChange, outLod) {

     if (outLod.level == 10) {
         canDrop = true;
         window[controlName + '_toolbarVar'].activate(esri.toolbars.Draw.POINT, { showTooltips: false });
     }
     else {
         window[controlName + '_toolbarVar'].deactivate();
         canDrop = false;
     }
 }
 ...
4

1 回答 1

1

为您的代码提供一个匿名的本地范围,而不是全局编写所有内容:

(function(any, globals, you, need, to, pass, in, as, an, instance){
  //All code local to your control goes here
  global = "etc..."

....
}(any, globals, you, need, to, pass, in, as, an, instance));

通过将全局变量作为自身传入,它们的本地版本会覆盖全局变量并阻止交互。

编辑:要从外部 JS 文件执行此操作,只需将代码声明为单个函数,并在每次加载控件时调用一次。然后,您只需在模板中包含一次 JS 文件:

在js文件中:

var myFuncLib = function(any, globals, you, need, to, pass, in, as, an, instance){
      //All code local to your control goes here
      global = "etc..."

    ....
    };

在您的控制中:

<script>
myFuncLib(any, globals, you, need, to, pass, in, as, an, instance);
</script>

传入的全局变量可能是特定于控件、DOM 元素、其他库资源等的 clsses/id。

这个解决方案也接近称为“模块模式”的库模式。有很多关于这个主题的好资源,其中最重要的是 CommonJS 规范(http://wiki.commonjs.org/wiki/Modules/ 1.1 ) 用于在库中实现它,以及许多使用这种模式的脚本加载器。

于 2013-07-23T17:46:47.540 回答