1

これに関する他の投稿をいくつか見ましたが、それらの回答からの回答は私にとってはうまくいきません。

他の応答:

Google マップの geocoder.geocode() コールバック関数をバインドするにはどうすればよいですか

Backbone.js と Google マップ - これとリスナーの問題

私のコード:

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 行目)

4

3 に答える 3

2

名前で参照できるはずなので、 this.marker が問題だと思います。

google.maps.event.addListener(marker, 'click', this.openSite(id));
于 2012-08-04T05:37:18.857 に答える
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);

これが機能する理由を最もよく説明できる人に答えます。

于 2012-08-05T21:09:58.633 に答える
-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.');
        }
    }
});
于 2012-11-09T21:57:00.190 に答える