Total Backbone js noob and I'm trying to understand whether the api I'm working with that returns json is either ill suited for backbone (or ill suited for anything), or if I just don't know how collections and models work enough yet in Backbone.
I know that the collection's fetch is returning the json correctly, it just may be how I'm processing the response. What is confusing is I don't really know what a proper fetched collection would like like and where the models are stored after fetching. It appears that what I want to be the models are stored as objects within the collection's models' attributes... is that right?
Also, I suppose as a second question, it seems that more or less my collection isn't parsing each model but rather only creates one model that contains my collection of models. I'm not sure how but I'd like that to be the other way around, one collection of my models. Any pointers?
Let me lay out some of the code and then I'll provide a sample of the json response (my sample will only include 3 objects), and a console log of the fetched collection. Really appreciate the help and any suggestions. Thanks!
My bootstrap file:
//statusApp.js
(function($){
var statusGroup = new app.StatusCollection();
var deferred = statusGroup.fetch({
data: {
action: "get_my_status_collection"
}
});
/* wait till fetch is complete */
$.when(deferred).then(function(){
console.log('returned collection', statusGroup);
var statusGroupView = new app.allStatusView({ collection: statusGroup});
$(".service-statuses").html(statusGroupView.render().el);
var statusRouter = new app.Router();
Backbone.history.start();
});
})(jQuery);
and below is a sample of the response received showing the all the nested nodes it comes with from the server. You'll see in my collections' parse function only returns the "objects" node, and I don't need the rest (and it may not work with these top level nodes?)
{
"component":{
"status":"2",
"count":"3",
"objects":{
"80":{
"name":"Calendar",
"parent":"0",
"status":"3",
"description":"Exchange Calendar",
"comment":""
},
"220":{
"name":"Solution Services",
"parent":"0",
"status":"3",
"description":"",
"comment":""
},
"2":{
"name":"Tech Portal",
"parent":"0",
"status":"2",
"description":"",
"comment":""
},
}
},
"in_maint":[],
"success":true
}
Here is a console log of the returned json from the collections fetch:
statusGroup
d {length: 1, models: (...), _byId: Object, url: (...), trigger: function…}
[object Object]: undefined
get [object Object]: function () {
set [object Object]: function (newval) {
__backboneDebugger__appComponentInfo: window.__backboneAgent.AppComponentInfo
__backboneDebugger__isInstancePatched: true
_byId: Object
initialize: function () {
length: 1
models: Array[1]
0: d
__backboneDebugger__appComponentInfo: window.__backboneAgent.AppComponentInfo
__backboneDebugger__isInstancePatched: true
_changing: false
_events: Object
_pending: false
_previousAttributes: Object
attributes: Object
2: Object
comment: ""
description: ""
name: "Tech Portal"
parent: "0"
status: "3"
get 2: function () {
set 2: function (newval) {
80: Object
comment: ""
description: "Exchange Calendar"
name: "Calendar"
parent: "0"
status: "2"
get 80: function () {
set 80: function (newval) {
220: Object
comment: ""
description: ""
name: "Solution Services"
parent: "0"
status: "3"
get 220: function () {
set 220: function (newval) {
watchers: Object
__proto__: Object
get attributes: function () {
set attributes: function (newval) {
changed: Object
cid: (...)
get cid: function () {
set cid: function (newval) {
collection: (...)
get collection: function () {
set collection: function (newval) {
id: (...)
get id: function () {
set id: function (newval) {
initialize: (...)
sync: function (){return b.sync.apply(this,arguments)}
trigger: function (a){if(!this._events)return this;var b=g.call(arguments,1);if(!j(this,"trigger",a,b))return this;var c=this._events[a],d=this._events.all;return c&&k(c,b),d&&k(d,arguments),this}
urlRoot: (...)
get urlRoot: function () {
set urlRoot: function (newval) {
watchers: Object
__proto__: f
get 0: function () {
set 0: function (newval) {
length: 1
pop: function () {
push: function () {
reverse: function () {
shift: function () {
slice: function () {
sort: function () {
unshift: function () {
watchers: Object
__proto__: Array[0]
get models: function () {
set models: function (newval) {
sync: function (){return b.sync.apply(this,arguments)}
trigger: function (a){if(!this._events)return this;var b=g.call(arguments,1);if(!j(this,"trigger",a,b))return this;var c=this._events[a],d=this._events.all;return c&&k(c,b),d&&k(d,arguments),this}
url: (...)
get url: function () {
set url: function (newval) {
watchers: Object
__proto__: f
My collection:
// allStatus.js
var app = app || {};
// A group (array) of Status models
app.StatusCollection = Backbone.Collection.extend({
model: app.singleStatus,
url: "/remote/api/status_json",
parse: function(response){
//return only the nested objects that will be our models
return response.component.objects;
}
});
My Collection view:
// allStatusView.js
var $ = jQuery.noConflict();
var app = app || {};
app.allStatusView = Backbone.View.extend({
tagName: "ul",
render: function() {
this.collection.each(this.addStatus, this);
return this;
},
addStatus: function(status) {
var statusView = new app.singleStatusView({ model: status });
this.$el.append(statusView.render().el);
}
});
My single view:
// singleStatusView.js
var $ = jQuery.noConflict();
var app = app || {};
app.singleStatusView = Backbone.View.extend({
tagName: "li",
className: "service-status",
template: _.template( $("#statusElement").html() ),
render: function() {
var statusTemplate = this.template(this.model.toJSON());
this.$el.html(statusTemplate);
return this;
}
});
Here's how you'd get the "objects" into the format your collection wants:
app.StatusCollection = Backbone.Collection.extend({
model: app.singleStatus,
url: "/remote/api/status_json",
parse: function (response){
var obj = response.component.objects;
// add the additional properties that won't be in your "models"
// to the collection object directly if you want them
this.status = response.component.status;
this.count = response.component.count;
// convert the "objects" object to an array and return
// the resulting array
return _.map(obj, function (value, key) {
return obj[key];
});
}
});
I added the other properties from the "component" to the collection object directly, but this isn't necessary - they're only there if you needed to keep those as well. You could do the same thing with the other properties at the end that aren't part of "component".