Reputation: 193
I am sort of a backbone.js n00b so please bear with me.
I am trying to dynamically generate a list of contacts using backbone.js, and attach an onclick event handler to each, to no avail. My views are rendering fine, but click event does not register. Here is my code:
App.Views.Contact = Backbone.View.extend({
initialize: function() {
this.render();
},
events: {
'click': 'select',
},
select: function(event) {
console.log('contact selected');
},
render: function() {
$('#contacts').append(tmplContact(this.model.toJSON()));
}
});
UPDATE: here is the code for the corresponding collection
App.Collections.Contact = Backbone.Collection.extend({
initialize: function() {
this.bind('reset', function() {
console.log('COLLECTION RESET');
});
},
model: App.Models.Contact,
comparator: function(model) {
return model.get('name');
}
});
UPDATE #2: collection initialization and population
App.Collections.roster = new App.Collections.Contact;
function getContacts() {
socketRequest('friends', function(data) {App.Collections.roster.reset(data)});
}
UPDATE #3: model definition
App.Models.Contact = Backbone.Model.extend({
initialize: function() {
this.set({id: this.get('token')});
this.set({avatar: parseAvatar(this.get('avatar'))});
this.set({name: parseName(this.toJSON())});
this.set({view: new App.Views.Contact({model: this})});
},
defaults: {
username: ''
}
});
Upvotes: 2
Views: 2523
Reputation: 6605
You need to use the View.el property in order to get the events working.
App.Collections.Contact = Backbone.Collection.extend({
initialize: function() {
this.bind('reset', function() {
console.log('COLLECTION RESET');
});
},
model: App.Models.Contact,
comparator: function(model) {
return model.get('name');
},
render: function() {
;
}
});
App.Views.Contacts = Backbone.View.extend({
el: '#contacts',
initialize: function() {
this.collection = new App.Collection.Contact;
this.collection.bind('reset', this.render, this);
var that = this;
socketRequest('friends', function(data) {
this.reset(data);
});
},
render: function() {
$(this.el).html('put your template here');
this.collection.each(this.addOne, this);
return this;
},
addOne: function(contact) {
var view = new App.Views.Contact({model: contact});
contact.view = view; // in case you need the ref on the model itself
$(this.el).append(view.render().el);
}
});
App.Views.Contact = Backbone.View.extend({
el: '',
tagName: 'div',
events: {
'click': 'select',
},
select: function(event) {
console.log('contact selected');
},
render: function() {
$(this.el).html(htmltmplContact(this.model.toJSON()));
return this;
}
});
a small improvement to your model code:
(notice that i removed the view creation, this is important!)
App.Models.Contact = Backbone.Model.extend({
parse: function(c) {
c.id = c.token;
c.avatar = parseAvatar(c.avatar);
c.name = parseName(c);
return c;
},
defaults: {
username: ''
}
});
and to kick things off:
App.Views.roster = App.Views.Contacts;
Upvotes: 4