Reputation: 3522
I have a backbonejs app that has a parent view like:
var LibraryView = Backbone.View.extend({
initialize: function(options) {
if (options) {
_.extend(this, options);
}
this.render();
alert(this.model); //Alerts Object Object like it's supposed to
_.each(this.model.get("library").books, function(book){
var bookView = new BookView({
el: $('#books'),
book: book,
model: this.model
});
bookView.render();
});
}
});
and my bookView looks like:
var BookView = Backbone.View.extend({
initialize: function(options) {
if (options) {
_.extend(this, options);
}
alert(this.model); // Alerts undefined
}
});
Basically, I'm trying to pass this.model from LibraryView to BookView, but when I do this, BookView's alert(this.model)
alerts Undefined?
I should mention that when I alert(this.book)
on my BookView, it's not undefined.
Upvotes: 0
Views: 28
Reputation: 88
Your question relates to the way that this
is defined. What this
means in the body of a function is controlled by how you called the parent function. Luckily, _.each
allows you to pass in the context (context is what this equates to in the body of the function) as an optional third argument. Docs here: http://underscorejs.org/#each.
The unfortunate part is that this only binds the value of this for the first function, which is the anonymous function you passed into the _.each
function. This does not bind this
for when you call the BookView
constructor since it is a separate function. When you call a function it creates a separate scope, meaning a different value for this(among other things). One solution is to use bind
for your constructor.
Try this:
_.each(this.model.get("library").books, function(book){
var bookView = new BookView({
el: $('#books'),
book: book,
model: this.model
}).bind(this);
bookView.render();
}, this);
Further reading can be found here on different ways this
is defined and how to use _.bind
and _.bindAll
: http://blog.bigbinary.com/2011/08/18/understanding-bind-and-bindall-in-backbone.html
Upvotes: 0
Reputation: 2261
This is because this
has changed context within the _.each. There are a million of posts about it so i won't explain.
End you each like this (with a this) to keep context:
_.each(this.model.get("library").books, function(book){
var bookView = new BookView({
el: $('#books'),
book: book,
model: this.model
}, this);
also look into Underscore's _.bindAll http://underscorejs.org/#bindAll
Upvotes: 1