Experiences on the Front Lines of User Interfaces and Web Development

Recursive Collection in Backbone Model

I'm working on a project that is using Browserify modules with Backbone. I will share more details on the full setup and build process I have working, but for today I wanted to share a fun problem I had with recursive models.

I wanted a Backbone Model X to have a children attribute that was a Backbone Collection of more X models. By using separate modules for everything to keep the code clean, that added an extra element to overcome.

My solution (at least for now, and definitely open to other approaches!) was the following which defined the model, then the collection, then further defined the model once a reference to the collection could be had:

// ----- models/tree.js ------
var Backbone = require("backbone");

var Tree = Backbone.Model.extend({  
  sync: function() {
    return false;
  },

  ...
});

// Require the collection, passing a reference to the model
var Trees = require('./../collections/trees')(Tree);

// Now that both model and collection are defined
//  make the initialize method construct a nested collection
Tree.prototype.initialize = function(attributes) {  
  this.children = new Trees(attributes.children);
};

// just export my model 
module.exports = Tree;  
// ----- collections/trees.js ------
module.exports = function(Model) {  
  var Backbone = require("backbone");

  return Backbone.Collection.extend({
    model: Model
  });
};

By the way I looked into NestedModels repo but I could not get it to require correctly with browserify. It seems I'm not alone. This would have solved the recursive/circular require issue in a similar (but more elegant) way, as well as given me some other features for models, but for now I don't need them so I did not chase down the require bug.

Their solution I believe would have looked something like this:

var Tree = Nested.Mode.extend();

Tree.define({  
    defaults : {
        children : Tree.Collection
    }
});
comments powered by Disqus