Muhambi
Muhambi

Reputation: 3522

Passing variable for model issue

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

Answers (2)

Bee
Bee

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

Laurens Kling
Laurens Kling

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

Related Questions