简体   繁体   中英

Binding a callback to this in Backbone.js

This is probably pretty simple, but for the life of me I can't figure out why this isn't binding correctly.

In my main view:

initMap: function() {
    forge.logging.log('... Initializing map');
    var createMap = function(position) {
        var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude, true);
        var options = {
            zoom: 15,
            center: latLng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        this.map = new google.maps.Map(document.getElementById('map_canvas'), options);
        this.addMarkers();
    };
    _.bind(createMap, this);
    forge.geolocation.getCurrentPosition(createMap);
    forge.logging.log('Created map ...');
},
addMarkers: function() {
    alert('addMarkers');
    forge.logging.log('... Adding markers');
    var tempData = ["xxxxxxxx",
                    "xxxxxxx",
                    "xxxxxxxx"];

    _.each(tempData, function(addr){
        google.maps.Geocoder.geocode({'address': addr}, function(res, status){
            if (status == google.maps.GeocoderStatus.OK) {
                new google.maps.Marker({
                    map: this.map,
                    position: res[0].geometry.location
                });
            }
        });
    });

    forge.logging.log('Added markers ...');
}

For some reason, the this.addMarkers() doesn't seem to be called. I'm guessing it's because this isn't bound correctly. The map shows up perfectly fine however.

How should I bind this to my createMap callback function?

From the fine manual :

bind _.bind(function, object, [*arguments])

Bind a function to an object , meaning that whenever the function is called, the value of this will be the object . Optionally, bind arguments to the function to pre-fill them, also known as partial application .

 var func = function(greeting){ return greeting + ': ' + this.name }; func = _.bind(func, {name : 'moe'}, 'hi'); func(); => 'hi: moe' 

The documentation could be a little more explicit but the important bit is in the example:

func = _.bind(func, ...)

So _.bind returns the bound function, it doesn't modify the function in-place. You want to say this:

createMap = _.bind(createMap, this);

or maybe this:

var createMap = function(position) { ... };
forge.geolocation.getCurrentPosition(_.bind(this, createMap));

Perhaps you're confused by using _.bindAll in other places. The _.bindAll function looks like it modifies the functions in-place but it is really modifying the object in place so this:

_.bindAll(obj, 'm1', 'm2');

is, more or less, doing this internally:

obj.m1 = _.bind(obj, obj.m1);
obj.m2 = _.bind(obj, obj.m2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM