2009-06-04 112 views
1

我有以下功能。 除Push,Pop和Remove方法外,一切正常。這些方法應該由事件處理程序調用。這個事件是由google maps api發起的。如何從事件處理程序調用公共方法

問題是,當事件被觸發時,找不到這些方法。我有一個「推送未定義」錯誤消息。

我試過這個但這不起作用。

如何從事件處理程序調用公共方法?

謝謝你們

function Track(mapContainer) { 
var map = mapContainer; 
var points = new Array(); 

var isEditMode = false; 

var clickListener; 

this.Push = function(point) { ... } 

this.Pop = function() { ... } 

this.Remove = function(point) { ... } 

//Enable/disable the marker placements 
this.PlaceWaypoint = function(isPlacing) { 
    if (isPlacing != true) { 
     if (clickListener != null) { 
      google.maps.event.removeListener(clickListener); 
      clickListener = null; 
     } 
    } else { 
     clickListener = map.AddEvent("click", function(event) { 
      if (!IsDoubleClick()) { 
       var point = map.PlaceMarker(new WayPoint(event.latLng)) 
       point.RemoveListener(function() { Remove(point); }); 
       Push(point); 
      } else { 
       Pop(); 
      } 
     }); 
    } 
} 
} 

回答

3

你有封閉/綁定問題。一個慣例是經常用它來指定一個變量,稱爲self,後者可以用來代替這個,這要歸功於JS的閉包屬性。

function Track(mapContainer) { 
    var map = mapContainer, 
     points = new Array(), 
     isEditMode = false, 
     clickListener, 
     // Make a variable self that points to this, that can be used inside closures 
     // where the original context is lost 
     self = this; 

    this.Push = function(point) { ... } 

    this.Pop = function() { ... } 

    this.Remove = function(point) { ... } 

    //Enable/disable the marker placements 
    this.PlaceWaypoint = 
     function(isPlacing) { 
      if (isPlacing != true) { 
       if (clickListener != null) { 
        google.maps.event.removeListener(clickListener); 
        clickListener = null; 
       } 
      } else { 
       clickListener = map.AddEvent("click", function(event) { 
        if (!IsDoubleClick()) { 
         var point = map.PlaceMarker(new WayPoint(event.latLng)) 
         point.RemoveListener(function() { Remove(point); }); 
         // Use the closure reference self instead of this 
         self.Push(point); 
        } else { 
         // Use the closure reference self instead of this 
         self.Pop(); 
        } 
       }); 
     }; 
} 
2

所有流行的第一和推送不是全局的,第二本在內部範圍內有其他含義。因此,您可以使用關閉並將「」重命名爲更多全局範圍的變量。

function Track(mapContainer) { 

//.... 
var $this = this; 

//Enable/disable the marker placements 
this.PlaceWaypoint = function(isPlacing) { 
    if (isPlacing != true) { 
     if (clickListener != null) { 
      google.maps.event.removeListener(clickListener); 
      clickListener = null; 
     } 
    } else { 
     clickListener = map.AddEvent("click", function(event) { 
      if (!IsDoubleClick()) { 
       var point = map.PlaceMarker(new WayPoint(event.latLng)) 
       point.RemoveListener(function() { $this.Remove(point); }); 
       $this.Push(point); 
      } else { 
       $this.Pop(); 
      } 
     }); 
    } 
} 
} 
+0

它可能是更好的範圍這對函數的前面添加var,否則如果我們有多個Track實例,$ this變量將被覆蓋,並在錯誤的實例上調用方法。 – PatrikAkerstrand 2009-06-04 10:05:41

2

this總是指當前功能的情況下,因此,如果你在你的事件處理程序使用this它指的是功能的Track函數調用this,而不是this

創建訪問外部範圍的this封閉,你需要分配一個this到可以從內部函數訪問一個新的變量:

var self = this; 
this.PlaceWaypoint = function(isPlacing) { 
    // ... 
    self.Pop(); 
    // ... 
} 
相關問題