Search code examples
javascriptbackbone.jsunderscore.jsbackbone-viewsbackbone-events

Passing arguments on top of those passed by trigger() in backbone.js


I have a method that passes up an argument in a nested view in Backbone, like such:

page.get('condition') ? this.trigger('someEvent', object) : this.trigger('someOtherEvent', object);

As I understand it, this code will pass object to 'someEvent' or 'someOtherEvent' as the first argument to the callback specified in the listener for that event.

My listener (in the parent view file) looks like:

this.parentView.on('someEvent', this.someFunction('extraArgument'), this);

By default, if the second parameter was just this.someFunction, I assume that the first argument to that function would be object. My issue is that I want to pass 'extraArgument' in addition to the implicitly passed object.

As such, I structure the signature of this.someFunction like this:

someFunction: function(object, extraArg) {
    ...
}

However, debug statements within the function reveal that object is in fact the extraArgument I passed manually, and that extraArg is undefined in the scope of the function. How can I pass the extraArgument without overwriting the argument passed up from the child view?


Solution

  • When you say this:

    this.parentView.on('someEvent', this.someFunction('extraArgument'), this);
    

    you're calling this.someFunction right there when the argument list for this.parentView.on is being built. Then whatever this.someFunction('extraArgument') returns is bound as the callback for the 'someEvent' event. Your someFunction probably doesn't return a function so this on call won't do anything useful.

    Sounds like you want to partial evaluate this.someFunction so that you create a new function that is just like this.someFunction but the first argument is always 'extraArgument'. Underscore offers _.partial for just that purpose:

    partial _.partial(function, *arguments)

    Partially apply a function by filling in any number of its arguments, without changing its dynamic this value.

    So you'd say:

    this.parentView.on(
        'someEvent',
        _(this.someFunction).partial('extraArgument'),
        this
    );
    

    You can also use _.bind for this if you want to set the this along the way.