J'ai un module que j'ai créé pour Google Maps v3 que j'essaye de convertir en constructeur de vue de Backbone.js.Backbone.js avec Google Maps - problèmes avec ceci et les auditeurs
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 « cette » est gérée.
Au départ, je n'ai pas les méthodes et plutôt ces deux dans le bloc initialize dragMarker et 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);
});
Le problème que je rencontrais avec cette première approche est que « cette » à l'intérieur de ces fonctions anonymes visées "this.marker" et "this.map" respectivement. Le problème avec cette première approche était que dans le premier écouteur, je n'avais aucun moyen de faire référence à "this.map" et donc je ne pouvais pas faire de panTo(). Avec le second écouteur, je n'avais aucun moyen de faire référence à "this.marker" et je ne pouvais donc pas recentrer la carte autour de ce marqueur en utilisant setPosition(). J'ai alors pensé que je pourrais retirer les fonctions anonymes dans les écouteurs et les déclarer comme des méthodes de la vue, que j'effectuerais alors un _.bindAll (ceci, "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 "this.dragMarker()" et "this.dragMap()" ont été évalués immédiatement au lieu d'être évalués en tant que rappel lorsque l'événement "dragend" est déclenché.
Pas de problème, je pensais puis enveloppé 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 » ne « this.dragMarker » fait plus référence à l'objet parent, j'ai construit, mais à la place de se référer à "this.marker" à nouveau. Le même problème se produit avec le deuxième écouteur.
Je suis complètement coincé ici. Quelqu'un at-il des idées sur la façon dont je résous cela?
La méthode correcte pour attacher un gestionnaire d'événements est la suivante: 'google.maps.event.addListener (this.marker," dragend ", this.dragMarker);' (sans les parenthèses). Mais cela ne résoudra pas votre problème de contexte. –