backbone.js events and el

11,438

Your problem is that the events on GridView:

events: {
    'click .grid-view': 'okay'
}

say:

when you click on a descendent that matches '.grid-view', call okay

The events are bound with this snippet from backbone.js:

if (selector === '') {
  this.$el.on(eventName, method);
} else {
  this.$el.on(eventName, selector, method);
}

So the .grid-view element has to be contained within your GridView's this.el and your this.el is <div class="grid-view">. If you change your events to this:

events: {
    'click': 'okay'
}

you'll hear your cows (or "hear them in your mind" after reading the alert depending on how crazy this problem has made you).

Fixed fiddle: http://jsfiddle.net/ambiguous/5dhDW/

Share:
11,438
siyegen
Author by

siyegen

Updated on June 01, 2022

Comments

  • siyegen
    siyegen almost 2 years

    Okay, so I've read several other questions regarding Backbone views and events not being fired, however I'm still not getting it sadly. I been messing with Backbone for about a day, so I'm sure I'm missing something basic. Here's a jsfiddle with what I'm working with: http://jsfiddle.net/siyegen/e7sNN/3/

    (function($) {
    
        var GridView = Backbone.View.extend({
            tagName: 'div',
            className: 'grid-view',
            initialize: function() {
                _.bindAll(this, 'render', 'okay');
            },
            events: {
                'click .grid-view': 'okay'
            },
            okay: function() {
                alert('moo');
            },
            render: function() {
                $(this.el).text('Some Cow');
                return this;
            }
        });
    
        var AppView = Backbone.View.extend({
            el: $('body'),
            initialize: function() {
                _.bindAll(this, 'render', 'buildGrid');
                this.render();
            },
            events: {
                'click button#buildGrid': 'buildGrid'
            },
            render: function() {
                $(this.el).append($('<div>').addClass('gridApp'));
                $(this.el).append('<button id="buildGrid">Build</button>');
            },
            buildGrid: function() {
                var gridView = new GridView();
                this.$('.gridApp').html(gridView.render().el);
            }
    
        });
    
        var appView = new AppView();
    
    })(jQuery);
    

    The okay event on the GridView does not fire, I'm assuming because div.grid-view does not exist when the event is first bound. How should I handle the binding and firing of an event that's built on a view dynamically? (Also, it's a short example, but feel free to yell at me if I'm doing anything else that I shouldn't)

  • siyegen
    siyegen over 12 years
    That worked, thanks. In general, if I want to bind an event to the element the view itself is creating, I'd leave out the selector? I tested that and it works with another view, just making sure that's the right way to go about things.
  • mu is too short
    mu is too short over 12 years
    @siyegen: Right. Have a look at the first branch of the backbone.js snippet I included; if there is no selector, then the event is bound directly to this.el using $(this.el).bind(eventName, method);, if there is a selector then the event is bound with delegate.
  • Jashwant
    Jashwant over 11 years
    but what when I want to fire event only when this.el has grid-view class ?
  • mu is too short
    mu is too short over 11 years
    @Jashwant: You'd probably have to check this.$el.hasClass('grid-view') inside the click handler or manually add and remove a raw click handler as needed without going through events.
  • Jashwant
    Jashwant over 11 years
    @muistooshort, Okay so there's no direct way.