I'm trying to use a very static starting set of data to bind to a backbone collection. In the code below, I create my model, give it an initialization function, and create a starting data set for a property called dataArray
.
In the collection, if I understand this correctly, I assign the model to be a single new instance of the model type I just created.
When I attempt to access the model in the collection from the view (via the render
function), however, I'm being told by Chrome's debugger that there are not models in the collection.
Trying to learn Backbone on the fly so any hints/tips/suggestions would be greatly appreciated.
Model
var DataPoint = Backbone.Model.extend({
initialize: function (x) {
this.setDefaults();
},
defaults: {
dataArray: ""
},
randomize: function () {
$.each(dataArray, function (key, item) {
this.contract = Math.random() * (140000 - 100000 + 1) + 100000;
});
},
setDefaults: function() {
dataArray = [{ "label": "0/7yrs", "contract": 108530.17, "annReturn": "1.20%" },
{ "label": "1/7yrs", "contract": 111830.17, "annReturn": "1.63%" },
{ "label": "2/7yrs", "contract": 115311.17, "annReturn": "2.07%" },
{ "label": "3/7yrs", "contract": 118984.65, "annReturn": "2.52%" },
{ "label": "4/7yrs", "contract": 122859.65, "annReturn": "2.98%" },
{ "label": "5/7yrs", "contract": 126947.77, "annReturn": "3.46%" },
{ "label": "6/7yrs", "contract": 131260.74, "annReturn": "3.94%" },
{ "label": "7/7yrs", "contract": 135810.92, "annReturn": "4.44%" }];
}
});
Collection
var DataSeries = Backbone.Collection.extend({
model: new DataPoint(),
fetch: function () {
},
randomize: function () {
this.each(function (m) {
m.randomize();
});
}
});
View
var BarGraph = Backbone.View.extend({
"el": "#graph",
options: {barDemo: ""},
initialize: function (options) {
_.bindAll(this, "render", "frame");
this.collection.bind("reset", this.render);
this.collection.bind("change", this.render);
this.options.barDemo = d3.selectAll($(this.el)).append("svg:svg")
.attr("width", width)
.attr("height", height + 60);
this.collection.fetch();
},
render: function () {
//This displays in the console as empty brackets: []
console.log(this.collection.models);
//This naturally throws an error saying cannot read propety of undefined
var data = this.collection.models.attributes.dataArray;
},
frame: function () {
//this.chart.append("line").attr("y1", 0).attr("y2", h - 10).style("stroke", "#000");
//this.chart.append("line").attr("x1", 0).attr("x2", w).attr("y1", h - 10).attr("y2", h - 10).style("stroke", "#000");
}
});
Starting jQuery function
$(function() {
var dataSeries = new DataSeries();
new BarGraph({
collection: dataSeries
}).render();
setInterval(function () {
Randomize();
}, 2000);
});
You seem to be a little confused about how Colllection
s work. The model
property of the collection is not meant to be a Model
instance at all: it's designed to be a Model
class. So, this line:
model: new DataPoint(),
should really be:
model: DataPoint
This is likely what is causing your problem. When you fetch
a Collection
Backbone uses the model
property to instantiate each new member of the collection. In other words, if your fetch returns:
[{a: 1}, {b: 2}];
the Collection
will do the following (essentially; the details aren't quite the same but this is close enough for explanatory purposes):
this.add(new DataPoint({a: 1}))
this.add(new DataPoint({b: 2}))
but back when your model
was a DataPoint
instance, what Backbone was doing was:
var x = new DataPoint();
this.add(new x({a: 1}))
this.add(new x({b: 2}))
which wouldn't have resulted in any Model
s being added to your Collection
.
Also, you seem to be a little confused about the models
property of a Collection
. You have this:
var data = this.collection.models.attributes.dataArray;
but the models
property of a Collection
's is an array of Model
instances, not a Model
itself, so it has no attributes
property. Each individual Model
instance in the Collection
does have an attributes
property though, and you can access it by using the Collection
invoke
method:
var data = this.collection.invoke('toJSON');
P.S. One last thing: your DataSeries
Collection
has no url
(or urlRoot
) property defined, which means your fetch
won't work because Backbone has no idea where to fetch the data from. The url
property should be set to a URL
which returns the JSON for 1+ models.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments