0

I am creating multiple objects and binding to the same handler. My requirement is I want to send particular value to handle when it is called.

Code:

sliderObj = [];
for(i=0;i<3;i++)
{
    sliderObj[i] = this._turntableSlider = new SliderView();
    sliderObj[i].on("change:value", this._handleChangeSpeedSlider);
}

When handler is called for sliderObj[0] want to send value 0 similarly 1 for sliderObj[1] etc.

Please help me out how to do that.

Hemant
  • 1,961
  • 2
  • 17
  • 27

2 Answers2

2

Try using .bind():

sliderObj[i].on("change:value", this._handleChangeSpeedSlider.bind(this, i));

Simple demo

T J
  • 42,762
  • 13
  • 83
  • 138
  • This is the idiomatic way to achieve what you want. The first parameter of `.bind` is the value for `this`. Every subsequent parameter does the following (as stated in the linked documentation): "Arguments to prepend to arguments provided to the bound function when invoking the target function." So, in this example, `_handleChangeSpeedSlider` will receive the the following parameters (in order): `function _handleChangeSpeedSlider(i, model, options)`. – Matt Kahl Mar 17 '17 at 02:51
1

Prefer listenTo over on.

Passing the index

Simplest solution would be to wrap the callback into an anonymous function.

But since we're looping and value of i will change, we need to create a simple function which returns a new function using the frozen value of i. (This is similar to using TJ's bind answer)

function getChangeSpeedHandler(index) {
    return function() {
        this._handleChangeSpeedSlider(index);
    }
}

for (i = 0; i < 3; i++) {
    var slider = sliderObj[i] = new SliderView();
    this.listenTo(slider, "change:value", getChangeSpeedHandler(i));
}

Passing the slider view

Assuming the value of i in the handler is only used to get the right sliderObj, you could pass the slider view directly.

function getChangeSpeedHandler(slider) {
    return function() {
        this._handleChangeSpeedSlider(slider);
    }
}

for (i = 0; i < 3; i++) {
    var slider = sliderObj[i] = new SliderView();
    this.listenTo(slider, "change:value", getChangeSpeedHandler(slider));
}

Delegating the event handling to the slider view

If you want to handle changes inside the SliderView, it should handle the event itself.

this.listenTo(this.model, 'change:value', this.onValueChange);

Triggering custom events

If it's really the parent that needs to know the slider and their number is dynamic, you could pass the i value to the SliderView and then it could trigger a custom event.

In the slider view:

var SliderView = Backbone.View.extend({
    initialize: function(options) {
        options = options || {};
        this.index = options.index;
        // ...
    },
    onValueChange: function(model, value, options) {
        this.trigger('slider:change', value, this.index, this);
    },
});

Then in the parent:

initialize: function() {
    for (i = 0; i < 3; i++) {
        var slider = sliderObj[i] = new SliderView({ index: i });
        this.listenTo(slider, "slider:change", this._handleChangeSpeedSlider);
    }
},
_handleChangeSpeedSlider: function(value, index, sliderView) {
    // handle the change
}
Community
  • 1
  • 1
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129