Alx
Alx

Reputation: 6285

Retrieve Backbone Collection from Model and keep it as a Collection

I'm currently fooling around with backbone.js and came across some wierd behaviour trying to create some relationships between models and collections.

So here is my Model/Collection

Element = Backbone.Model.extend({
  name: 'element'
});

Elements = Backbone.Collection.extend({
  name: 'elements',
  model: Element
});

Application = Backbone.Model.extend({
  name: 'app',
  initialize: function() {
    this.elements = new Elements(this.get('elements'));
  } 
});

When I retrieve the elements via application.get('elements') I get a 'false' asking if this new Object is an instanceof Backbone.Collection.

var gotElements = application.get('elements');
var isCollection = gotElements instanceof Backbone.Collection;

So am I doing something wrong, or do I have to create a new Collection-Instance and fill it up with the Collection I receive from the application?

Upvotes: 0

Views: 145

Answers (2)

mcbex
mcbex

Reputation: 444

In your initialize function doing this.elements sets a property called 'elements' directly on your model (so model.elements will be your Backbone collection). The problem is when you try to retrieve this.elements by calling application.get('elements'), you will see it returns undefined (which is why it is not an instance of a Backbone collection).

In order for a model attribute to be retrievable using model.get it needs be set with model.set(attribute). If you examine the model in the console you will see the difference. model.set(myData) adds your data to the model's attributes hash. model.myData = myData adds a 'myData' property directly to the model.

To get this to work you can do the following:

Element = Backbone.Model.extend({
  name: 'element'
});

Elements = Backbone.Collection.extend({
  name: 'elements',
  model: Element
});

Application = Backbone.Model.extend({
  name: 'app',
  elements: null
});

var application = new Application({
  elements: new Elements()
});

var myElements = application.get('elements');

myElements should now be an empty Backbone Collection

Upvotes: 4

Thomas Junk
Thomas Junk

Reputation: 5676

Instead of putting your collection into another model, you should put it in the according view:

var ListView = new Backbone.View.extend({
     initialize:function(){
         this.Elements= new Elements();
         // more stuff to go
     },
     render:function(){
          _.forEach(this.Elements, function(){
         //Do rendering stuff of indivdual elements and get HTML
         });
         //put HTML in the DOM
     }
});

There is no need of a model containing a collection containing several models.

Edit: And instead of putting your app into a Model, you should put it into a view.

Upvotes: 0

Related Questions