我正在定义这个类:
function GMap(map, marker, geocoder) {
this.map = map;
this.marker = marker;
this.geocoder = geocoder;
this.setMarker = function(address) {
this.geocoder.geocode({'address' : address}, function(results, status) {
map.setCenter(results[0].geometry.location);
marker.setPosition(results[0].geometry.location);
});
}
}
如何从回调函数访问GMap的map
和marker
属性?
非常感谢。
答案 0 :(得分:5)
Function对象原型有一个“apply”方法,您可以使用该方法在函数中设置“this”的上下文。检查任何geocoder.code的API /代码,许多库将通过一个额外的参数为你处理这个问题,即:
this.someObj.someFn(params, callback, scope);
在someFn中,它将使用与此类似的回调:
callback.apply(scope || window, [callbackArg1, callbackArg2]);
这将使“回调”中的“this”上下文作为“范围”传递,或者如果没有传入任何内容,“this”将是窗口的全局上下文。一些javascript库还提供了一种创建回调函数委托的方法,该委托确保始终使用预期范围调用函数,无论它最终从哪里调用。一个例子是ExtJS's Function.createDelegate
如果您使用的库不提供内置功能,那么您可以在回调闭包中创建一个本地var引用,即:
this.setMarker = function(address) {
var thisGMap = this;
this.geocoder.geocode({'address' : address}, function(results, status) {
thisGMap.map.setCenter(results[0].geometry.location);
thisGMap.marker.setPosition(results[0].geometry.location);
});
}
答案 1 :(得分:1)
这是你要找的吗?
function GMap(map, marker, geocoder) {
this.map = map;
this.marker = marker;
this.geocoder = geocoder;
var currentGMap = this; // private variable bound to GMap constructor scope
this.setMarker = function(address) {
this.geocoder.geocode({'address' : address}, function(results, status) {
// currentGMap is available (yay closures)
currentGMap.map.setCenter(results[0].geometry.location);
currentGMap.marker.setPosition(results[0].geometry.location);
});
}
}
注意:地图和标记也通过闭包绑定,但我假设您希望在创建GMap实例后能够更改地图和标记属性。
编辑:是的,我看到凯文在他的最后一部分中也在我面前惊醒了这一点。
答案 2 :(得分:0)
我猜它是一张谷歌地图?你为什么要经过地图和标记呢?使它们成为全局变量(即:将var map;
置于所有函数的外部)然后您应该能够从任何地方访问它们。
在函数中重用变量名也是个坏主意。如果您首先将它们传递给函数,那么它们将成为函数变量,因此在函数中定义map,marker和geocoder是没有意义的,因为您已经可以使用map,marker和geocoder访问它们。 :)
答案 3 :(得分:0)
如果您使用的是jQuery,那么可以使用一个名为$.proxy()
的方法来更改上下文(将函数的“this”设置为您想要的任何内容)。
this.setMarker = function(address) {
this.geocoder.geocode({'address' : address}, $.proxy(function(results, status) {
this.map.setCenter(results[0].geometry.location);
this.marker.setPosition(results[0].geometry.location);
}, this));
}