You have two problems that are keeping your initialize
from working:
- There is no
printText
in scope.
_.bind
and _.bindAll
behave differently.
The first is easy to fix, you want to use this.printText
, not just printText
.
_.bind
binds a single function to a this
and returns that bound function; _.bindAll
, on the other hand, binds several named functions to a this
and leaves the bound functions attached to the specified this
. So, doing this:
_.bind(printText, this);
doesn't do anything useful as you're throwing away the bound function. You'd want to do this:
this.printText = _.bind(this.printText, this);
Or more commonly in Backbone apps, you'd use _.bindAll
:
_.bindAll(this, 'printText');
Now you have a functioning initialize
and you'll have the right this
inside printText
and we can move on to fixing printText
. I think you want to extract the text from the <li>
that was clicked; you can do this like this:
printText: function(ev) {
console.log($(ev.target).text());
}
But that still doesn't work and we're left to wondering what's going on here. Well, Backbone binds events to a view's el
so let us have a look at that:
var print = Backbone.View.extend({
el : $('ul li.newItem'),
//...
When that Backbone.View.extend
runs, there won't be any li.newItem
elements in the DOM so you won't get a useful el
in that view. The usual approach here would be to have a view that looks like this:
var Print = Backbone.View.extend({
tagName: 'li',
events: {
'click': 'printText'
},
render: function() {
this.$el.text('Hello world ' + this.options.i);
return this;
},
printText: function(e){
console.log($(e.target).text());
}
});
We set tagName
to 'li'
and let Backbone create the <li>
by itself. Then we'd pass the counter value to the Print
view as an argument, Backbone will take care of leaving the argument in this.options.i
when we say new Print({ i: ... })
.
Now we just have to adjust the addItem
method in your ListView
to create new Print
s and add them to the <ul>
:
addItem: function(){
this.counter++;
var v = new Print({ i: this.counter });
this.$('ul').append(v.render().el);
}
Updated demo: http://jsbin.com/evoqef/10/edit
I've also made a few other changes:
- Use
this.$el
instead of $(this.el)
, there's no need to create something that's already available.
- Use
this.$()
instead of $('ul', this.el)
, same result but this.$()
doesn't hide the context at the end of the $()
function call and this.$()
is more idiomatic in Backbone.