Reputation: 582
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
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