1

私は以下の機能を持っています。Push、Pop、Removeメソッドを除いて、すべて正常に機能します。これらのメソッドは、イベントハンドラーによって呼び出される必要があります。このイベントは、GoogleMapsAPIによって発生します。

問題は、イベントが発生したときに、これらのメソッドが見つからないことです。「プッシュが定義されていません」というエラーメッセージが表示されます。

これで試しましが、うまくいきません。

イベントハンドラからパブリックメソッドを呼び出すにはどうすればよいですか?

みんなありがとう

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();
            }
        });
    }
}
}
4

3 に答える 3

3

クロージャ/バインディングの問題があります。JSのクロージャープロパティのおかげで、後でこれの代わりに使用できる、 selfと呼ばれる変数を割り当てるために頻繁に使用される1つの規則。

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();
                    }
                });
        };
}
于 2009-06-04T10:02:57.340 に答える
2

まず第一に、ポップアンドプッシュはグローバルではありません。第二に、内部スコープのこれには別の意味があります。したがって、クロージャを使用して、「this」の名前をよりグローバルスコープの変数に変更できます。

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();
            }
        });
    }
}
}
于 2009-06-04T10:01:14.423 に答える
2

this常に現在の関数のコンテキストを参照するためthis、イベントハンドラーで使用する場合は、関数でthisはなく、その関数呼び出しを参照しthisますTrack

this外部スコープのにアクセスするクロージャを作成するにthisは、内部関数からアクセスできる新しい変数にそれを割り当てる必要があります。

var self = this;
this.PlaceWaypoint = function(isPlacing) {
   // ...
   self.Pop();
   // ...
}
于 2009-06-04T10:08:48.123 に答える