如何为必应地图事件创建闭包

How to create a closure for a Bing Maps event?

本文关键字:事件 创建 闭包 地图      更新时间:2023-09-26

我有一个javascript问题,我认为是与闭包在循环类似:

如何在JavaScript中复制变量?JavaScript闭包内循环-简单的实际例子

我正在Bing地图上绘制一个引脚列表,并为每个引脚附加一个事件,以便可以为每个引脚显示一个信息框。每个pin应该有一个不同的信息框。问题是,当事件触发时,它总是显示循环最后一次迭代的最后一个信息框,而不是与触发事件的引脚一起显示的信息框。下面是带有循环构造的方法,我尝试创建闭包

失败了
monumentMap.plotData = function() {
        monumentMap.theMap.entities.clear();
        var monument = null
        var loc = null;
        for (var i = monumentMap.theData.length - 1; i >= 0; i--) {
            monument = monumentMap.theData[i];
            loc = new Microsoft.Maps.Location(monument.lat, monument.lon);
            // construct a bing pushpin and add it to the item data
            monument.pin = new Microsoft.Maps.Pushpin(loc, {
                icon: 'http://media.maps101.com/' + monument.pinImg
            });
            // construct a bing infobox and add it to the item data
            monument.infobox = new Microsoft.Maps.Infobox(loc, { // breakpoint 1
                title: monument.title,
                offset: new Microsoft.Maps.Point(-3, monument.pin.getHeight() - 5),
                zIndex: 999,
                visible: true
            });
            // add event listeners
            // doesn't work
            Microsoft.Maps.Events.addHandler(monument.pin, 'mouseover', function() {
                return function(infobox) {
                    monumentMap.displayInfobox(infobox);
                }(monument.infobox); // breakpoint 2: by the time this is executed monument.infobox is already "last not current"
            });
            // add the entities to the map view for this item
            monumentMap.theMap.entities.push(monument.pin);
        }
}

我很难理解为什么它不起作用。我在循环中设置了monument.infobox,如果我在标记为"断点1"的行上设置了一个断点,我可以看到monument.infobox在每次循环迭代中都发生了变化,但是当我到达"断点2"(直到事件触发才执行)时,它引用了我创建的最后一个infobox,而不是我在附加事件处理程序时附加到该引脚上的infobox。

到目前为止,我有一半希望这行monumentMap.theMap.entities.push(monument.pin);会在循环中添加一堆最后一个pin的副本,但它没有。它可以正常工作,并在每个循环迭代中添加一个不同的pin。

您需要将参数放在外部异常函数中。如果我是正确的:

Microsoft.Maps.Events.addHandler(monument.pin, 'mouseover', 
(function(infobox) {
  return function() {
    monumentMap.displayInfobox(infobox);
  }     
 })(monument.infobox));