I'm currently using Backbone + RequireJS. In my application, I display a tree widget that is constructed with the same Model with nested Collections. That is to say:
FooCollection
define(['backbone', 'models/foo'], function(Backbone, FooModel) {
var FooCollection = Backbone.Collection.extend({
model: FooModel
});
return FooCollection;
});
FooModel
define(['backbone', 'underscore'], function(Backbone, _) {
var FooModel = Backbone.Model.extend({
initialize : function() {
_.bindAll(this, 'adoptOne', 'adoptAll');
var self = this;
// Need to do it this way or RequireJS won't find it
require(['collections/foos'], function(FooCollection) {
self.foos = new FooCollection();
self.on('change:foos', function() {
self.foos.reset(self.get('foos'));
});
self.foos.on('reset', self.adoptAll);
self.foos.on('add', self.adoptOne);
self.foos.reset(self.get('foos');
});
},
adoptAll : function() {
this.foos.each(this.adoptOne);
},
adoptOne : function(foo) {
foo.parent = this;
}
});
return FooModel;
});
The above works. I don't get any errors and everything is constructed as expected. However...
// In a view
this.foos = new FooCollection();
this.foos.fetch({
success : function(foos) {
var treeView = new TreeView();
treeView.render(foos); // Doesn't work!!
}
});
The above doesn't work because of a sync problem: the TreeView gets rendered before the nested collections have finished creating (either because it takes longer to run the code or because it takes time to load 'collections/foos'.
Either way, I can fix it with this:
setTimeout(function() {
treeView.render(foos);
}, 100);
But that, of course, it's just a hack. In a production environment it could take more than 100 miliseconds and the code wouldn't work.
So, I guess that what I should do is to trigger some sort of event that my view listens to. However, my question to y'all is the following: when do I know that the entire collection of foos have been constructed and where do I attach the listener?
Thanks in advance!!