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

3 回答 3

3

你有一个关闭/绑定问题。由于 JS 的闭包属性,经常使用它来分配一个名为self变量的约定,以后可以使用它来代替this 。

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

首先Pop 和Push 不是全局的,其次this 在内部作用域中还有另一个含义。所以你可以使用闭包并将“ 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 回答