2011-01-21 65 views
0

代碼存儲的功能

for (var i:int = 0; i < markers.length; i++) 
{ 
    markers[i].addEventListener(MapMouseEvent.CLICK, function(e:Event):void 
    { 
     markers[i].openInfoWindow(infoWindows[i]); 
    }); 
    map.addOverlay(markers[i]); 
} 

我有標記在markers陣列的列表,並且infoWindow陣列中相關聯的InfoWindowOptions的列表的列表。

的問題

通過單擊該標記的時間和匿名函數調用,用於循環已完成和i現在等於markers.length。所以我在markers[i]infoWindows[i]上遇到了一個界限錯誤。

我想創建一個關聯函數的列表,並將其存儲在一個數組中。所以,我可以做這樣的事情,而不是:

for (var i:int = 0; i < markers.length; i++) 
{ 
    markers[i].addEventListener(MapMouseEvent.CLICK, markerListeners[i]); 
} 

所以我需要知道的是兩種,

  • 我如何能的函數引用列表存儲在一個陣列?
  • 有沒有更好的方法來做到這一點?

回答

2

有沒有更好的方法來做到這一點?

我會嘗試更好的方式來做到這一點。首先,最好避免每一個在addEventListener中放置一個匿名函數,因爲你無法移除這個監聽器,也不會被垃圾收集 - 所以你的應用程序會有內存泄漏。

即便如此,Dictionary將是完美的。

不是維護兩個單獨的數組,而是試圖將它們連接在一起,Dictionary的key:value語法將極大地簡化您的工作流程。

首先,你應該設置你的字典:

var markersDictionary:Dictionary = new Dictionary(true); 

//you didn't show how you create your arrays so I'm showing 
//you how to create a dictionary manually. 
//this can also be done in a loop 
markersDictionary[marker] = new InfoWindow(); // This should be whatever is in your infoWindows array 
markersDictionary[marker] = new InfoWindow(); 
markersDictionary[marker] = new InfoWindow(); 

我們添加監聽器:

for(var key:Object in markersDictionary) 
{ 
    var marker:Marker = markersDictionary[key]; 
    marker.addEventListener(MouseMapEvent.CLICK, markerClickhandler, false, 0, true); 
    //...false, 0, true is for weak event listeners, you should get in 
    // the habit of always doing this unless you have a reason to otherwise. 
{ 

,當然你需要定義markerClickhandler

function markerClickhandler(event:MouseMapEvent):void 
{ 
    var marker:Marker = event.target as Marker; 

    marker.openInfoWindow(InfowWindow(markersDictionary[marker]); 
} 
+0

+1詳細解釋。通過在addEventListener中使用弱引用參數可能會破壞內存泄漏,但匿名處理程序方法無論如何都是不好的。如果可以在點擊標記後完成,我也不會一次創建所有InfoWindows(這是問題作者的註釋)。 – alxx 2011-01-23 13:48:33

0

有沒有更好的方法來做到這一點?

好問題。標記應該是MapMouseEvent的目標,因此您可以使用常規函數並按目標區分標記。

0

爲避免出現邊界錯誤,您需要獲取的值而不是引用,該引用保存在您的匿名處理函數中。我敢肯定有來實現這一目標比下面更優雅的方式,但是這是我必須做的伎倆:

for (var i:int = 0; i < markers.length; i++) 
    { 
     markers[i].addEventListener(MapMouseEvent.CLICK, createMapMouseEventHandler(i)); 
     map.addOverlay(markers[i]); 
    } 
    ... 
} 

private function createMapMouseEventHandler(index:int):Function 
{ 
    return function(e:Event):void 
     { 
      markers[index].openInfoWindow(infoWindows[index]); 
     } 
} 

注意:如果markers和/或infoWindows是createMapMouseEventHandler的範圍之內您需要將它們作爲參數傳遞。