Backbone.js与谷歌地图 - 这个和听众的问题

时间:2010-12-07 16:54:25

标签: javascript google-maps google-maps-api-3 this backbone.js

我有一个我为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 Maps事件监听器以及“处理”这个问题。

我最初没有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”不再引用我构造的父对象,而是再次引用“this.marker”。第二个侦听器也会出现同样的问题。

我完全被困在这里。任何人对我如何解决这个问题都有任何想法?

2 个答案:

答案 0 :(得分:6)

使用dragend上调用的匿名函数并显式绑定。

_.bindAll(this, 'dragMarker', 'dragMap');
google.maps.event.addListener(this.marker, "dragend", this.dragMarker);
/* etc ... */

这种方式this将始终与CreateMap绑定,即使被调用超出上下文。

答案 1 :(得分:5)

我通过使用Javascript中常见的/ self hack解决了这个问题。

var self = this;

google.maps.event.addListener(this.marker, "dragend", function() {
  self.latlng = this.getPosition();
  self.map.panTo(self.latlng);
});

google.maps.event.addListener(this.map, "dragend", function() {
  self.latlng = this.getCenter();
  self.marker.setPosition(self.latlng);
});

如果有人有一个不需要这种黑客攻击的解决方案,我全都听见了。