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"
}
})
For every possibility where the new model is:
.add
,.push
,.create
,.set
,.reset
, or the collection's constructor.I found that hooking in the
_prepareModel
undocumented collection function works well.A generic collection
This collection can be used as-is to replace the default Backbone collection. It adds
onNewModel
fonction to override, that receives the new model instance and the optionsnew-model
event which sends the same data.And your own collection could be:
It is guarantee that
model
is a BackboneModel
instance insideonNewModel
.Proof of concept
I've managed to fix it by overriding collection's create method, I'm still unsure if this is the right way to go.