Search code examples
javascriptbackbone.js

Trouble with 'this' in Backbone View


So I have a backbone view for a google map.

'use strict';

var MapView = Backbone.View.extend({
  id: 'map-container',

  initialize: function() {
    this.model.set('map', new google.maps.Map(this.el, this.model.get('mapOptions')));
    this.render();
    this.map = this.model.get('map');

    this.poly = new google.maps.Polyline({
      strokeColor: '#000000',
      strokeOpacity: 1.0,
      strokeWeight: 3
    });
    this.poly.setMap(this.map);

    this.map.addListener('click', this.addLatLng);
  },

  render: function() {
    $('#map-container').replaceWith(this.el);
    return this;
  },

  addLatLng: function(event) {
    var path = this.poly.getPath();

    path.push(event.latLng);

    var marker = new google.maps.Marker({
      position: event.latLng,
      title: '#' + path.getLength(),
      map: this.map
    });
  }
});

My problem is in the addLatLng function. this.poly is undefined and I think it is because of where addLatLng is being called? But i'm not super sure. Is there a way that this.poly and this.map can be defined in addLatLng?


Solution

  • this.map.addListener('click', this.addLatLng); is your problem. You are registering it to run a specific function, but that function won't be bound to any context when it runs. You can use the Underscore bind function to ensure the function runs in the current context:

    var boundAddLatLong = _.bind(this.addLatLong, this);
    this.map.addListener('click', boundAddLatLong);
    

    If you were using some of the Backbone.Events functionality (on, listenTo, etc), it provides ways to provide the context that the function should run in. But whatever this.map is does not appear to do so.