Backbone Bootstrapped Collection Doesn't Initialize Correctly
Solution 1:
The Collection constructor looks like this:
var Collection = Backbone.Collection = function(models, options) {
//...this._reset();
this.initialize.apply(this, arguments);
//...this.reset(models, {silent: true, parse: options.parse});
//...
};
Step by step:
- The
this._reset()
call does athis.length = 0
. - The
this.initialize.apply(...)
is the call to yourinitialize
method. - The
this.reset(...)
will calladd
to add the models. Theadd
call will update the collection'smodels
andlength
properties.
So, when initialize
is called, you'll have this.length == 0
and this.models
will be an empty array since only _reset
will have been called here. Now we can easily see why this.each
doesn't do anything and why console.log(this.length)
says 0
.
But why does console.log(this)
tell us that we have a populated collection? Well, console.log
doesn't happen right away, it just grabs references to its arguments and logs something to the console a little bit later; by the time console.log
gets around to putting something in the console, you'll have gotten through (3) above and that means that you'll have the this.models
and this.length
that you're expecting to see. If you say
console.log(this.toJSON());
or:
console.log(_(this.models).clone())
you'll see the state of things when console.log
is called rather than the state of things when console.log
writes to the console.
The documentation isn't exactly explicit about what is supposed to be ready when initialize
is called so you're stuck tracing through the source. This isn't ideal but at least the Backbone source is clean and straight forward.
You'll notice that initialize
is called like this:
this.initialize.apply(this, arguments);
The arguments
in there means that initialize
will receive the same arguments as the constructor so you could look in there if you wanted:
initialize: function(models, options) {
// The raw model data will be in `models` so do what// needs to be done.
}
Solution 2:
You are bootstrapping incorrectly. You will need to use the Collection reset() method, and listen for a reset event in your collecton like so
Bootstrap code:
var collection = new MyCollection;
collection.reset(<?phpif ($data) { echo json_encode($data); } ?>);
Your collection code:
varMyCollection = Backbone.Collection.extend({
model: MyModel,
initialize: function() {
this.on("reset", this.foobar);
},
foobar: function(collection) {
console.log(this); // will be the sameconsole.log(this.length); // will equal 3this.each(function(model) {
console.log(model); // will output a console for each model.
});
}
});
Post a Comment for "Backbone Bootstrapped Collection Doesn't Initialize Correctly"