Search code examples
javascriptbackbone.js

How to set Backbone model's defaults based on collection attribute


I need all new MenuItem models to have menu attribute from parent collection. Here is a basic example that doesn't work (because this.collection is undefined in MenuItem's defaults function)

var MenuItem, Menu, menu;

MenuItem = Backbone.Model.extend({
  defaults: function() {
    return {
      menu: this.collection.name
    }
  },

  // Fake Backbone sync
  sync: function(method, model, options) {
    if(typeof model.cid != 'undefined') {
      var cid = model.cid;
      model.unset('cid').set({id:cid}, {silent:true});
    }
    options.success(model);
  }

});

Menu = Backbone.Collection.extend({
  model: MenuItem,
  initialize: function(options) {
    this.name = options.name;
  }
});

menu = new Menu({name: "footer"});

menu.create({title: "Page", url: "/page"}, {
  success: function(model){
    console.log(model.get("menu")) // expect to be "footer"
  }
})

Solution

  • I've managed to fix it by overriding collection's create method, I'm still unsure if this is the right way to go.

    create: function(attributes, options) {
      return Backbone.Collection.prototype.create.call(
        this,
        _.extend({menu: this.name}, attributes),
        options
      );
    }