Question

J'ai un module j'ai créé pour Google Maps v3 que je suis en train de se convertir en un constructeur de vue Backbone.js.

Voici mon module de vue à ce jour: Je vais vous expliquer les problèmes que je vais avoir après le 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);
  }

});

Le problème que je vais avoir est avec les écouteurs d'événements Google Maps et comment « cela » est géré.

Je n'ai pas d'abord les méthodes dragMarker et dragMap et au lieu de ces deux dans le bloc initialize:

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

Le I problème rencontré avec cette première approche est que « ce » à l'intérieur de ces fonctions anonymes appelé « this.marker » et « this.map » respectivement. Le problème avec cette première approche est que dans le premier auditeur, je n'avais aucun moyen de se référer à « this.map » et ne pouvait donc pas effectuer une panTo (). Avec le second auditeur, je n'avais aucun moyen de se référer à « this.marker » et ne pouvait donc pas le recentrera sur le plan que marqueur en utilisant setPosition ().

J'ai alors pensé que je pouvais tirer les fonctions anonymes dans les auditeurs et les déclarer comme méthodes de la vue, que je puis effectuer une _.bindAll (cela, « dragMarker », « dragMap »);

Le problème avec cette approche est que je devais alors d'écrire les auditeurs dans le bloc événement comme ceci:

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

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

Cela signifie que quand j'ai appelé le constructeur avec newmap = new pg.views.CreateMap; que le « this.dragMarker () » et « this.dragMap () » ont été évalués immédiatement au lieu d'être évalué comme une fonction de rappel lorsque l'événement « dragend » est déclenchée.

Pas de problème je pensais et enrubannées ceux dans les fonctions anonymes comme ceci:

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

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

Malheureusement, cela me ramène aussi à un problème plus tôt que « ce » dans « this.dragMarker » ne fait plus référence à l'objet parent, je construisais, mais au lieu de parler de « this.marker » à nouveau. Le même problème se produit avec le second auditeur.

Je suis complètement coincé ici. Tout le monde a des idées sur la façon dont je résoudre ce problème?

Était-ce utile?

La solution

Prenez les fonctions anonymes appelées sur dragend et se lient explicitement.

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

Cette this façon sera toujours liée à CreateMap même si elle est appelée hors contexte.

Autres conseils

Je résolu ce problème en utilisant le que / auto bidouille commun en 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);
});

Si quelqu'un a une solution qui ne nécessite pas ce hack, je suis toutes les oreilles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top