Backbone.js 与 Google 地图 - 有关此问题和侦听器的问题
我有一个为 Google Maps v3 创建的模块,我正在尝试将其转换为 Backbone.js 视图构造函数。
到目前为止,这是我的视图模块:我将在代码之后解释我遇到的问题:
pg.views.CreateMap = Backbone.View.extend({
tagName: "div",
className: "map",
events: {},
latitude: "-23.56432",
longitude: "-46.65183",
initialize: function() {
_.bindAll(this, 'render', 'dragMarker', 'dragMap');
this.latlng = new google.maps.LatLng(this.latitude, this.longitude);
var myOptions = {
zoom: 16,
center: this.latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map($(this.el)[0], myOptions);
this.marker = new google.maps.Marker({
map: this.map,
position: this.latlng,
draggable: true
});
google.maps.event.addListener(this.marker, "dragend", this.dragMarker());
google.maps.event.addListener(this.map, "dragend", this.dragMap());
},
render: function() {
return this;
},
dragMarker: function() {
this.latlng = this.marker.getPosition();
this.map.panTo(this.latlng);
},
dragMap: function() {
this.latlng = this.map.getCenter();
this.marker.setPosition(this.latlng);
}
});
我遇到的问题是 Google 地图事件侦听器以及如何处理“this”。
我最初没有dragMarker和dragMap方法,而是在初始化块中使用这两个方法:
google.maps.event.addListener(this.marker, "dragend", function() {
this.latlng = this.marker.getPosition();
this.map.panTo(this.latlng);
});
google.maps.event.addListener(this.map, "dragend", function() {
this.latlng = this.map.getCenter();
this.marker.setPosition(this.latlng);
});
我使用第一种方法遇到的问题是那些匿名函数中的“this”引用了“this.marker”和“this.map”分别。第一种方法的问题是,在第一个侦听器中,我无法引用“this.map”,因此无法执行 panTo()。对于第二个侦听器,我无法引用“this.marker”,因此无法使用 setPosition() 使该标记周围的地图居中。
然后我认为我可以提取侦听器中的匿名函数并将它们声明为视图的方法,然后我将执行 _.bindAll(this, "dragMarker", "dragMap");
这种方法的问题是,我必须在事件块中编写侦听器,如下所示:
google.maps.event.addListener(this.marker, "dragend", this.dragMarker());
google.maps.event.addListener(this.map, "dragend", this.dragMap());
这意味着当我使用 newmap = new pg.views.CreateMap; 调用构造函数时当触发“dragend”事件时,立即评估“this.dragMarker()”和“this.dragMap()”,而不是作为回调进行评估。
我想没问题,然后将它们包装在匿名函数中,如下所示:
google.maps.event.addListener(this.marker, "dragend", function() {
this.dragMarker();
});
google.maps.event.addListener(this.map, "dragend", function() {
this.dragMap();
});
不幸的是,这也让我回到了之前的问题,即“this.dragMarker”中的“this”不再引用我构造的父对象,而是引用再次“这个.标记”。第二个侦听器也会出现同样的问题。
我完全被困在这里了。有人对我如何解决这个问题有任何想法吗?
I have a module I created for Google Maps v3 that I'm trying to convert into a Backbone.js view constructor.
Here's my view module so far: I'll explain the problems I'm having after the code:
pg.views.CreateMap = Backbone.View.extend({
tagName: "div",
className: "map",
events: {},
latitude: "-23.56432",
longitude: "-46.65183",
initialize: function() {
_.bindAll(this, 'render', 'dragMarker', 'dragMap');
this.latlng = new google.maps.LatLng(this.latitude, this.longitude);
var myOptions = {
zoom: 16,
center: this.latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map($(this.el)[0], myOptions);
this.marker = new google.maps.Marker({
map: this.map,
position: this.latlng,
draggable: true
});
google.maps.event.addListener(this.marker, "dragend", this.dragMarker());
google.maps.event.addListener(this.map, "dragend", this.dragMap());
},
render: function() {
return this;
},
dragMarker: function() {
this.latlng = this.marker.getPosition();
this.map.panTo(this.latlng);
},
dragMap: function() {
this.latlng = this.map.getCenter();
this.marker.setPosition(this.latlng);
}
});
The problem I'm having is with the Google Maps event listeners and how "this" is handled.
I originally didn't have the dragMarker and dragMap methods and instead these two in the initialize block:
google.maps.event.addListener(this.marker, "dragend", function() {
this.latlng = this.marker.getPosition();
this.map.panTo(this.latlng);
});
google.maps.event.addListener(this.map, "dragend", function() {
this.latlng = this.map.getCenter();
this.marker.setPosition(this.latlng);
});
The problem I encountered with this first approach is that "this" inside those anonymous functions referred to "this.marker" and "this.map" respectively. The problem with this first approach was that in the first listener, I had no way of referring to "this.map" and therefore could not perform a panTo(). With the second listener, I had no way of referring to "this.marker" and therefore could not recenter the the map around that marker using setPosition().
I then thought that I could pull out the anonymous functions in the listeners and declare them as methods of the view, which I would then perform a _.bindAll(this, "dragMarker", "dragMap");
The problem with this approach is that I then had to write the listeners in the event block like so:
google.maps.event.addListener(this.marker, "dragend", this.dragMarker());
google.maps.event.addListener(this.map, "dragend", this.dragMap());
This meant that when I called the constructor with newmap = new pg.views.CreateMap; that the "this.dragMarker()" and "this.dragMap()" were evaluated immediately instead of being evaluated as a callback when the "dragend" event is triggered.
No problem I thought and then wrapped those up in anonymous functions like so:
google.maps.event.addListener(this.marker, "dragend", function() {
this.dragMarker();
});
google.maps.event.addListener(this.map, "dragend", function() {
this.dragMap();
});
Unfortunately this also brings me back to an earlier problem that the "this" in "this.dragMarker" no longer refers to the parent object I constructed, but instead refer to "this.marker" again. The same problem occurs with the second listener.
I'm completely stuck here. Anyone have any ideas on how I solve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
获取在
dragend
上调用的匿名函数并显式绑定。这样,即使在脱离上下文的情况下调用,
this
也将始终与 CreateMap 绑定。Take the anonymous functions called on
dragend
and bind explicitly.This way
this
will always be tied to CreateMap even if called out of context.我通过使用 Javascript 中常见的 that/self hack 解决了这个问题。
如果有人有不需要这种黑客的解决方案,我会洗耳恭听。
I solved this problem by using the that/self hack common in Javascript.
If anyone has a solution that doesn't require this hack, I'm all ears.