1

假設你有一個使用第三方JS API的用戶控件(使用dojo)。您有一個JS函數loadMap,它爲您的控件初始化一些全局變量,並將一些事件(從第三方API)連接到您的JS事件處理程序。在您的事件處理程序中,您需要使用在loadMap中定義的全局變量。用戶控制範圍內的全局JS變量?

問題: 如果我有這樣的控制在同一頁面中的多個實例,全局變量將覆蓋對方,難道不工作。

問:
我如何寫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

給你的代碼匿名本地範圍,而不是全局寫的一切:

(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文件,只有一次在你的模板:

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的具體

在js文件

DOM元素,其他庫資源等。

這個解決方案也接近一個叫做「模塊模式」的庫模式有很多很好的資源ava在這個話題上是可用的,其中不乏CommonJS規範(http://wiki.commonjs.org/wiki/Modules/1.1)在庫中的實現,以及許多使用這種模式的腳本加載器。

+0

我不知道我是否理解過路部分?如果我這樣做不會這意味着我需要在用戶控制代碼中的JS(與單獨的文件相比)? –

+0

如果代碼從外部變量中提取,例如從其所在的頁面或從另一個庫中提取,您只需要通過。經典的例子是將「JQuery」作爲「$」傳遞,以便$不會全局衝突,但可以在函數範圍內使用。我將編輯答案以顯示如何在外部使用。 – MaxPRafferty

+0

我花了幾個小時才弄清楚(謝謝:)),但似乎並非所有事件都正確連接。這樣做會影響腳本的行爲嗎? –