Backbone.js с Google Maps - проблемы с этим и у слушателей - PullRequest
7 голосов
/ 07 декабря 2010

У меня есть модуль, созданный для 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 и с тем, как обрабатывается «это».

Изначально у меня не было методов 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; что «this.dragMarker ()» и «this.dragMap ()» были оценены немедленно, а не как обратный вызов при срабатывании события «dragend».

Нет проблем, я подумал, а затем обернул их в анонимные функции, например:

google.maps.event.addListener(this.marker, "dragend", function() {
  this.dragMarker();
});

google.maps.event.addListener(this.map, "dragend", function() {
  this.dragMap();
});

К сожалению, это также возвращает меня к более ранней проблеме, заключавшейся в том, что «this» в «this.dragMarker» больше не ссылается на созданный мной родительский объект, а вместо этого снова ссылается на «this.marker». Та же проблема возникает со вторым слушателем.

Я полностью застрял здесь. У кого-нибудь есть идеи, как мне это решить?

Ответы [ 2 ]

6 голосов
/ 15 июня 2011

Возьмите анонимные функции, вызываемые на dragend, и выполните явное связывание.

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

Таким образом, this всегда будет привязан к CreateMap, даже если вызывается вне контекста.

5 голосов
/ 07 декабря 2010

Я решил эту проблему, используя хак that / self, распространенный в Javascript.

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

Если у кого-то есть решение, которое не требует этого взлома, я весь в ушах.

...