Reputation: 63687
I have some JSON response data that are multiple levels deep. However, I only need to retrieve part of it at any one time in a step-by-step wizard style page. In the first step of the wizard, a top-level object category_a
(which contains an array of objects) is needed, in the next step, another top-level object category_b
is used and so on.
At each step, backbone will create several ProductView
views and append to a div #photo_list
. Each ProductView
view will use the img
object of an element in the array.
Problem: How should I access the top-level objects one at a time, given my template file (which can be edited/improved) shown below which I try to make it as simple as possible.
Example JSON response
Object names like category_a
and the number of objects can vary
{"category_a":[
{"product_id":6283,
"img":"http:\/\/www.mysite.com\/img\/6283_5e093.jpg"},
{"product_id":6284,
"img":"http:\/\/www.mysite.com\/img\/6284_5e093.jpg"}
],
"category_b":[
{"product_id":6283,
"img":"http:\/\/www.mysite.com\/img\/6283_5e093.jpg"},
{"product_id":6284,
"img":"http:\/\/www.mysite.com\/img\/6284_5e093.jpg"}
]
}
Backbone.js Code
productList
currently contains the entire JSON response
ProductCollection = Backbone.Collection.extend({
url: '/api/someurl',
model: Product
});
ProductListView = Backbone.View.extend({
el: '#photo_list',
initialize: function() {
this.collection.bind('reset', this.render, this);
},
render: function() {
this.collection.each(function(product, index){
$(this.el).append(new ProductView({ model: product }).render().el);
}, this);
return this;
}
});
ProductView = Backbone.View.extend({
tagname: 'div',
className: 'photo_box',
template: _.template($('#tpl-PhotoListItemView').html()),
render: function() {
this.$el.html(this.template( this.model.toJSON() ));
return this;
}
});
Creating the Collection+Views
this.productList = new ProductCollection();
var self = this;
self.productListView = new ProductListView({ collection: self.productList });
this.productList.fetch();
Template Snippet
<div class="photo_container">
<img src="<%= img %>" class='photo' />
</div>
Upvotes: 1
Views: 544
Reputation: 456
I've done something similar (appending items from a JSON response), but I'm doing it all in one view, which may or may not work for your needs. Thought I would share just in case it's helpful.
My template looks like this:
<div id="folders" data-role="content">
<div class="content-primary">
<ul data-role="listview" id="foldersListView" data-filter="true">
<!-- insert folders here -->
<% for (var i = 0; i < folders.length; i++) { %>
<% var folder = folders[i]; %>
<li id=<%= folder.displayName %>><h3><%= folder.displayName %></h3><span class="ui-li-count"><%= folder.count %></span><ul></ul></li>
<% } %>
<!-- done inserting -->
</ul>
</div>
</div>
Then in the initialize function of my view, I simply have to pass the JSON object and the template will step through each item for me.
initialize : function() {
_.bindAll(this, "render", "logoutAction");
this.template = _.template($("#folders").html(), { folders : app.folders.toJSON() });
// Add the template HTML to the body.
$(this.el).html(this.template);
},
And after sharing all that, I think the easier solution for you may be to just step through each item when creating the views.
this.productList = new ProductCollection();
var self = this;
productListJSON = self.productList.toJSON()
$.each(productListJSON, function(product) {
new ProductListView({ product: productListJSON[product].product });
});
Upvotes: 1