Domanda

Ho un modulo che ho creato per Google Maps v3 che sto cercando di convertire in una visione costruttore Backbone.js.

Ecco il mio modulo di vista finora: mi spiego i problemi che sto avendo dopo il codice:

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

});

Il problema che sto avendo è con gli ascoltatori di eventi di Google Maps e su come "questo" è gestita.

Io inizialmente ho non ho i metodi dragMarker e dragMap e invece questi due nel blocco di inizializzazione:

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

Il problema che ho riscontrato con questo primo approccio è che "questo" all'interno di quelle funzioni anonime denominato "this.marker" e "this.map", rispettivamente. Il problema con questo primo approccio è che nel primo ascoltatore, ho avuto modo di riferirsi a "this.map" e quindi non poteva eseguire un panto (). Con il secondo ascoltatore, non ho avuto modo di riferirsi a "this.marker" e quindi non poteva centrare nuovamente la mappa intorno a quel marcatore utilizzando setPosition ().

Ho poi pensato che ho potuto tirare le funzioni anonime negli ascoltatori e dichiarare come metodi di visualizzazione, che avrei poi eseguire un _.bindAll (questo, "dragMarker", "dragMap");

Il problema di questo approccio è che ho poi dovuto scrivere gli ascoltatori nel blocco evento in questo modo:

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

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

Questo significava che quando ho chiamato il costruttore con newmap = new pg.views.CreateMap; che il "this.dragMarker ()" e "this.dragMap ()" sono stati valutati immediatamente invece di essere valutato come un callback quando viene attivato l'evento "dragend".

Nessun problema ho pensato e poi avvolto quelli in funzioni anonime in questo modo:

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

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

Purtroppo questo porta anche a me di nuovo ad un problema in precedenza che il "questo" in "this.dragMarker" non si riferisce all'oggetto genitore ho costruito, ma invece fare riferimento a "this.marker" di nuovo. Lo stesso problema si verifica con il secondo ascoltatore.

Sono completamente bloccato qui. Qualcuno ha qualche idea su come posso risolvere questo?

È stato utile?

Soluzione

Prendere le funzioni anonime invitato dragend e si legano in modo esplicito.

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

Questa this modo sarà sempre legato a CreateMap anche se chiamato fuori dal contesto.

Altri suggerimenti

Ho risolto questo problema utilizzando il che / sé mod comune in 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);
});

Se qualcuno ha una soluzione che non richiede questo hack, sono tutto orecchi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top