每次运行此循环时,markers数组中的每个标记都会被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;
}
};
}());
答案 0 :(得分:1)
因此,正如我在原始评论中提到的,除非您明确创建并传递副本,否则JavaScript对象和数组始终通过引用传递。您的代码中没有任何内容本身就是错误的并且不会导致此问题 - 实际上这是leaflet如何在内部处理对象引用的问题。避免这种情况的方法是对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有点不同于我。他把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]);