Mdd
Mdd

Reputation: 4420

How to create a Backbone Collection with data that is not flat

I am not sure how to create a Backbone Collection using the following data, and wonder how it should be approached.

The items property in the JSON makes sense to me to use as a collection since it is an array already. But is there a good way of getting the other information available to the collection, or keeping it persistent in case it needs to be referenced in a view? How should I handle the following data format for a collection?

Here's some example data and code:

{
"page": 1,
"total": 1000,
"items": [
    {
        "title": "title of item 1",
        "color": "green",
        "type": [
            {
                "isStandard": "Yes",
                "size": "Large"
            },
            {
                "isStandard": "No",
                "size": "Medium"
            }
        ],
        "price": "9.99"
    },
    {
        "title": "title of item 2",
        "color": "blue",
        "type": [
            {
                "isStandard": "No",
                "size": "XXL"
            },
            {
                "isStandard": "No",
                "size": "XXS"
            }
        ],
        "price": "19.99"
    },
    {
        "title": "title of item 3",
        "color": "red",
        "type": [
            {
                "isStandard": "No",
                "size": "Small"
            },
            {
                "isStandard": "Yes",
                "size": "Large"
            }
        ],
        "price": "229.99"
    }
],
"date": "Wed Oct 08 2014 21:04:05 GMT-0500 (CDT)"
}

var SomeModel = Backbone.Model.extend({});

var SomeCollection = Backbone.Collection.extend({
  model: SomeModel,
  
  url: 'https://api.mongolab.com/api/1/databases/backbonecollectiontest/collections/backbonecollection?apiKey=qcVNgNb-s1X4WJkLeRDfykxqtMG-ezkC',
  
  parse: function(response) {
      // Returning only the items data.  But this will be missing data in the response
      // that is not included in the items property
      return response[0].items;
  }
});

var SomeView = Backbone.View.extend({
    el: '.js-container',
  
    initialize: function() {
        this.collection = new SomeCollection();
      
        this.collection.fetch();
      
        this.listenTo(this.collection, 'sync', this.render); 
    },
  
    template: _.template( $('#some-template').html() ),
  
    render: function() {
      
      this.$el.html( this.template( {collection: this.collection.toJSON()} ) );
      
   }
});

var someView = new SomeView();
<div class="js-container">
</div>

<script type="text/template" id="some-template">
    <h3>How should I get the 'page', 'total', and 'date' properties in the data here?</h3>
    <% _.each(collection, function(element, index) { %>
      <p>
        <%- element.title %>, 
        <%- element.color %>, 
        <% _.each(element.type, function(ele, i) { %>
          <%- ele.isStandard %>,
          <%- ele.size %>,
        <% }); %>
        <%- element.price %>
      </p>
    <% }); %>

</script>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>

Upvotes: 1

Views: 499

Answers (1)

Evgeniy
Evgeniy

Reputation: 2921

Looks like u need nested model here:

Here is an prototype to catch the idea, for more info checkout this post

1) create model and collection for items

var Item = Backbone.Model.extend({
    defaults: {
        "title": "no-title",
        "color": "no",
        "type": [],
        "price": "0"
    }
});

var ItemsCollection = Backbone.Collection.extend({
    model: Item
});

2) create parent model, looks like page in your case:

var PageModel = Backbone.Model.extend({
    defaults: {
        page: 0,
        date: 'now',
        total: 0,
        items: []
    },
    initialize: function() {
        var items = this.get('items');
        this.set('items', new ItemsCollection(items));
    }  
});

If you have an array in JSON resp, u can create PageCollection as well.

Upvotes: 1

Related Questions