0

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!!

Poly
  • 195
  • 2
  • 8
  • Maybe you should try something else: http://stackoverflow.com/questions/4881059/how-to-handle-circular-dependencies-with-requirejs-amd. – Loamhoof Jun 02 '13 at 16:58
  • Why are you trying to instantiate a new `FooCollection` inside your `FooModel`'s `initialize` method? That seems like a road to infinite recursion. – idbehold Jun 02 '13 at 17:04
  • @Loamhoof I gave `'exports'` a try using BackboneRelational and it doesn't seem to work. See [this](http://stackoverflow.com/questions/16886091) @idbehold It doesn't actually create an infinite loop since `FooModel`'s are only instantiated on `reset`, `set` or `add`. Since I'm only triggering `reset`, if `self.get('foos')` is empty, no instantiation is executed. – Poly Jun 02 '13 at 19:00

0 Answers0