用户控件范围内的全局JS变量?

时间:2013-07-23 17:23:25

标签: javascript asp.net user-controls global-variables multiple-instances

假设您有一个使用第三方JS API的用户控件(使用dojo)。你有一个JS函数loadMap,它为你的控件初始化一些全局变量,并将一些事件(从第三方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;
     }
 }
 ...

1 个答案:

答案 0 :(得分: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>

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

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