Nathan Ridley
Nathan Ridley

Reputation: 34396

Backbone.js - why does my delegateEvents selector not work?

I have a view that contains nested views of the same type. Because of this, my delegateEvents selector needs to be careful to only select the top-level elements and not the elements in the child views.

The following code, used within the context of my view, successfully selects the element I wish to bind:

var $link = this.$('> .node > .indent > a'); // success!

The delegateEvents object, using the same selector, does not hook up the event at all:

events: {
    'click > .node > .indent > a': 'toggleGrouped' // fail :(
}

Note that I have confirmed that the event hookup does work with other, simpler selectors, so it's not an issue with rendering.

What am I doing wrong?

Upvotes: 4

Views: 2279

Answers (3)

darvelo
darvelo

Reputation: 325

Another way to do this I think might be to just take the child selectors > out of the events hash and in the event handler use event.stopPropagation() like so:

toggleGrouped: function (evt) {
  evt.stopPropagation();

  // event handling code
}

The first parent up the chain listening for that event will get it, then prevent it from bubbling up to any others that might have also caught the event.

Upvotes: 2

Paul
Paul

Reputation: 18597

It probably has to do with jQuery's delegate event not liking the > .node > .indent > a selector.

You can confirm this by adding the following line of code in your view's render method. (this is what Backbone is doing in delegateEvents)

$(this.el).delegate('> .node > .indent > a', 'click', this.toggleGrouped);

If it still doesn't work then the issue has to do with the delegate event and not backbone.

A workaround is to bind to the click event after all the rendering is done in the render method.

this.$('> .node > .indent > a').click(this.toggleGrouped);

You will also have to bind the context of toggleGrouped in the initialize method since it's no longer being automatically bound.

initialize: function() {
  _.bindAll(this, 'toggleGrouped');
}

Upvotes: 6

Nathan Ridley
Nathan Ridley

Reputation: 34396

Found the answer. delegateEvents uses jQuery.delegate(), which for some reason doesn't accept selectors that start with a child descender:

http://api.jquery.com/delegate/#comment-66006048

Upvotes: 2

Related Questions