Scot
Scot

Reputation: 582

Backbone view delegateevents won't work

I'm having an issue with getting delegateEvents to work.

here's my View definition:

//the "." in Mustache templating simply means it will iterate through an array of JSON objects
var locationViewTemplate = '<div class="ui-content-panel ui-content-panelLocationView ui-corner-all "><div><ul class="ui-content-list">' +
'{{#.}}' +
'<li><span>{{Name}}</span> <a href="#">edit</a></li>' +
'{{/.}}' +
'{{^.}}' +
'<li>No Locations Defined</li>' +
'{{/.}}' +
'</ul></div><input type="text" id="locationName"> <input class="locationAdd" type="button" title="Add Location" id="locationAdd" value="Add"></div>';


//module: Location
(function(Location) {
//define Model
Location.LocationModel = Backbone.Model.extend({
    initialize: function () {
        this.entityName = 'location';
    }
});

//define collection
Location.LocationCollection = Backbone.Collection.extend({
    model: Location.LocationModel,
    initialize: function () {
        this.entityName = 'location';
    },
    getAllLocations: function () {
        this.functionName = 'GetAll';
        this.fetch();
    }
});

//define View(s)
Location.LocationListView = Backbone.View.extend({
    events: {
        'click #locationAdd': 'addClickEvent'
    },
    render: function () {
        $(this.el).html(Mustache.render(locationViewTemplate, this.collection.toJSON()));
        //this.delegateEvents();

        return this;
    },
    initialize: function() {
        this.render();
        //this.delegateEvents();
    },
    addClickEvent: function (){
        alert('this is the function');
    }

});


})(vHub.module('location'));

Here's the definition of the button that the selector '#locationAdd' should find:

<input class="locationAdd" type="button" title="Add Location" id="locationAdd" value="Add">

I also call delegateEvents from the document ready event:

//steal the JS libs that we need
steal('json2.js','mustache.js','underscore.js', 'jquery-ui-1.8.18.custom.min.js')
.then('backbone.js')
.then('./common.js')
.then('./modules/FrameTop.js', './modules/Location.js')
.then('./modules/AdminBasicsPage.js')
.then( function() {
$(function(){
initializeApp();

var Location = vHub.module('location');
var lc = new Location.LocationCollection();
lc.getAllLocations();

var lv = new Location.LocationListView({collection: lc});

$('#content').html($(lv.el).html());


});
});

I've looked at what i could find here on stackOverflow, and tried some of those suggestions. But none have been successful yet. Any help would be greatly appreciated. Thanks!

Upvotes: 0

Views: 1916

Answers (2)

Josh Earl
Josh Earl

Reputation: 18361

Funny you should ask... I just solved a similar problem in an app I'm working on, and lo and behold, this was the top question under the Backbone.js tag.

Not sure that we were having the same issue, but my problem was that the button I was trying to attach to was actually outside of the scope of my view. Backbone views have an el property, and click events are only attached to children of that root element.

In my app, I had a list view which had a ul as it's root element. Both my button and the list were siblings inside of a div tag:

<div>
    <ul id="my-list-view"></ul>
    <button id="save">Save</button>
</div>

My code worked initially because I set up the click handler using a raw jQuery selector in the initialize function. I was actually reaching outside of the scope of my view and attaching the click handler, which wasn't at all my intention. When I refactored to try to make it fit the Backbone convention, it failed to fire.

Try using a regular jQuery selector in your code, and if it works, you probably have a similar scoping problem. Like this:

initialize: function() {
    $('#locationAdd').click(addClickEvent);
    this.render();
}

That's not the Backbone way of doing this--you want to use the events hash like you have done in your code. But you may need to nest your collection view inside of a control-level view.

Upvotes: 4

tomswift
tomswift

Reputation: 359

I took what I could from the code you posted and here is a little working example. If you want to post more code I could possibly help debug. As Elf mentioned, no need to explicitly call delegateEvents().

Upvotes: 1

Related Questions