2017-03-08 38 views
1

每次運行此循環時,marker數組中的每個標記都會將其圖標從let icon = iconLoader.getIcon(data[index][5]);的結果中覆蓋。 讓每個標記具有最後加載的圖標,而不是在for循環的每次傳遞期間加載圖標。來自內部的值,用於循環覆蓋循環外的數據

我認爲將圖標傳遞給閉包基本上會通過值傳遞它,防止它被覆蓋在閉包範圍之外,但這似乎不適用於我。我錯過了什麼?

var markers = [] 
for (var index in data) {  
    let icon = iconLoader.getIcon(data[index][5]); 
    var createMarker = (function (i) { 
     return function() { 
      var marker = new L.marker([data[index][2], data[index][3]]) 
       .setIcon(i)  
      markers.push(marker); 
     } 
    })(icon); 
    createMarker(); 
} 

var iconLoader = (function() { 
    var icon = L.icon({ 
     // options 
    });  
    return { 
     getIcon: function (iconName) { 
      // do stuff to get icon 
      return icon; 
     } 
    }; 
}()); 

JSFiddle

+0

對象和數組除非你創建一個副本 – mhodges

+0

你也永遠不會調用由您IIFE..at返回的功能至少不總是按引用傳遞無論如何,你提供的代碼。 – mhodges

+0

你可以發佈'setIcon'函數的內容嗎?最好是標記類的結構呢? – mhodges

回答

1

所以,正如我在原來的評論中提到,JavaScript對象和數組引用始終被傳遞,除非你明確地創建並傳遞一個副本。代碼中沒有任何內容是錯誤的,並且不會導致此問題 - 實際上,傳單在內部如何處理對象引用時存在問題。避免這種情況的方法是對iconLoader.getIcon()的結果執行深層副本。如果你使用的是jQuery,你可以通過使用$.extend()來簡單地做到這一點。

for (var index in data) { 
    let icon = $.extend(true, {}, iconLoader.getIcon(data[index][2])); 
    var marker = new L.marker([data[index][0], data[index][1]]) 
    .setIcon(icon);  
    markers.push(marker); 
} 

如果不是,您可以看看非jQuery解決方案 - 它不是理想的,但它們無處不在。

+1

完全適合我。謝謝! –

0

當mhodges正在寫他的答案時,我正在打字。我會繼續發佈,因爲這是一個不同的解決方案,也爲我解決了這個問題。

在看完mhodges的演示後,我注意到他已經設置了圖標加載器,與我的圖標有點不同。他有iconloader爲對象...

var iconLoader = { 
    getIcon: function (elem) { 
     return elem; 
    } 
} 

而我被設置爲關閉...

var iconLoader = (function() { 
    var icon = L.icon({ 
     // options 
    });  
    return { 
     getIcon: function (iconName) { 
      // do stuff to get icon 
      return icon; 
     } 
    }; 
}()); 

我想,也許我可以嘗試設置它有點不同,看看如果這有所作爲,VOILA!

const proto = { 
     getIcon (iconName) { 
      var icon = L.icon({ 
       // options 
      }); 
      // do stuff to get icon 
      return icon; 
     } 
    }; 

function factoryIcon() { 
    return Object.create(proto); 
} 

,然後抓起圖標,

const iconFactory = factoryIcon(); 
let icon = iconFactory.getIcon(data[index][5]);