Search code examples
backbone.jsbackbone-viewsbackbone-events

jQuery like event maps for Backbone listenTo?


I have a view which needs to listenTo the change of a model attribute. When that change event fires, I have to call two different callback functions. I know this can be easily accomplished using .on like

model.on({
     'change:title' : updateTitle,
     'change:title' : updateSummary
});

But when using listenTo I have to write this in multiple lines

this.listenTo(model, 'change:title', updateTitle);
this.listenTo(model, 'change:title', updateSummary);

Is there a way to avoid having to re-write the listenTo statement multiple times? Or does this issue mean that my code isn't structured properly and I should rethink my approach?

A simple alternative is that I call updateSummary from updateTitle, but I was just wondering if this can be accomplished using object.listenTo


Solution

  • does this issue mean that my code isn't structured properly and I should rethink my approach?

    I don't see any problem having two (or more) listeners registered to the same event. That's a core point of decoupling. You could have different (decoupled) Views that update their contents when the same event is triggered.

    I don't know the rest of your code, but I suppose your updateSummary listens to other change events apart from the change:title:

    this.listenTo(model, 'change:summary', updateSummary);
    

    In this case you are registering the same listener (updateSummary) to different events (change:title and change:summary). And that's ok, with listenTo you are sort of connecting different view updates to different model events in a decoupled way.

    Is there a way to avoid having to re-write the listenTo statement multiple times?

    Maybe an overkill, but you could use the functions that underscore provides to have something like this:

    _.each([updateTitle, updateSummary], _.partial(this.listenTo, model, 'change:title'), this);
    

    A simple alternative is that I call updateSummary from updateTitle, but I was just wondering if this can be accomplished using object.listenTo

    I'm afraid that listenTo only accepts a callback function, not an array of functions.

    If you are still worried about having listenTo on the same event multiple times, you can create a more general function, let's say update, that updates both title and summary, and register only this more general update function:

    this.listenTo(model, 'change:title', update);
    

    or if you don't want another function, you can use an anonymous one:

    this.listenTo(model, 'change:title', function() {updateTitle(); updateSummary();});