带有骨干的Google Maps API,如何绑定事件

时间:2012-08-04 05:32:53

标签: google-maps-api-3 backbone.js underscore.js

我已经看过其他几篇关于此的帖子,但这些回复的答案对我不起作用。

其他答复:

How do I bind a google maps geocoder.geocode() callback function

Backbone.js with Google Maps - problems with this and listeners

我的代码:

var ns = namespace('camelcase.geomanager.map');

ns.Site = Backbone.Model.extend({
    url: '/site'
});

ns.Sites = Backbone.Collection.extend({
    model: ns.Site
});

ns.MapView = Backbone.View.extend({

    initialize: function() {
        this.markers = new Array();

        // Create the Google Map
        var mapOptions = {
                center: new google.maps.LatLng(-34.397, 150.644),
                zoom: 8,
                mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        this.googleMap = new google.maps.Map(this.$(".mapCanvas")[0], mapOptions);

        // Register events
        this.collection.on('add', this.addSite, this);
        this.collection.on('remove', this.removeSite, this);
    },

    addSite: function(model) {
    // Get model attributes
    var elementId = model.get('elementId');
    var latitude = model.get('latitude');
    var longitude = model.get('longitude');
    var id = model.get('id');
    var notes = model.get('notes');
    var title = ""+id;

    // Create icon and marker
    var icon = '/resources/img/elements/' + elementId + '_marker.png';
    var latLng = new google.maps.LatLng(latitude, longitude);
    var marker = new google.maps.Marker({
        position: latLng,
        title: title,
        map: this.googleMap,
        icon: icon
    });

    // Load info window
    var siteBubbleTemplate = _.template($('#siteBubbleTemplate').html());
    var siteContent = $(siteBubbleTemplate({
        siteId: id,
        siteNotes: notes
    }))[0];

    var infoWindow = new google.maps.InfoWindow({
        content: siteContent
    });

    // Show info window when clicking on marker
    _.bindAll(this, this.openSite);
    google.maps.event.addListener(marker, 'click', this.openSite(id));

        this.markers.push({
            id: id,
            marker: marker,
            infoWindow: infoWindow
        });

    },

    openSite: function(id) {
        var marker;
        for (var c=0; c<this.markers.length; c++) {
            marker = this.markers[c];

            // Open the appropriate marker info window
            if (marker.id == id) {
                marker.infoWindow.open(googleMap, marker.marker);
            }

            // Close the rest
            else {
                marker.infoWindow.close();
            }
        }
    }
});

违规行:

google.maps.event.addListener(marker, 'click', this.openSite(id));

在firebug中报告错误:

  

TypeError:func未定义

     

underscore.js(第482行)

3 个答案:

答案 0 :(得分:2)

我怀疑this.marker是问题,因为你应该能够通过名字来引用它。

google.maps.event.addListener(marker, 'click', this.openSite(id));

答案 1 :(得分:1)

看起来这是一个范围问题。我用以下代码解决了我的问题:

// Show info window when clicking on marker
_.bindAll(this);
var _self = this;
var doSomething = function(event) {
    _self.openSite({
        event: event
    });
};
google.maps.event.addListener(marker, 'click', doSomething);

我会给出最能解释其原因的人的答案。

答案 2 :(得分:-1)

在模型/集合事件处理程序中,Backbone将“this”设置为引发事件的模型/集合。如果在视图的initialize()中调用_.bindAll(this),则“this”将设置为事件处理程序中的视图。看看这个jsfiddle:http://jsfiddle.net/9cvVv/339/,看看当你取消注释_.bindAll(this)时会发生什么;

var MyView = Backbone.View.extend({
    initialize: function() {
        // TODO: uncomment this line
        // _.bindAll(this);
        this.collection.bind('myEvent', this.onDoSomething);
    },

    updateCollection: function() {
        this.collection.doSomething();
    },

    onDoSomething: function() {
        if (this.models && typeof this.models.length === 'number') {
            alert('"this" is a collection.');
        }
        else if (this.collection) {
            alert('"this" is the view.');
        }
        else {
            alert('"this" is something else.');
        }
    }
});