Asked By: Anonymous
I have a JSON file that will create my ParentModel
as well as populate the child Records
collection.
ParentModel : Backbone.Model.extend({
initialize: function() {
this.set({ records: new Records(this.get("records")) });
}
});
And the Records collection is just a basic Backbone collection that maps to a Record model.
The problem is that I need the child to know about the parent, so each Record
model has to have a parent property on it. So for now I’ve just been adding this to the bottom of the initialize method:
var self = this;
this.get("records").each(function(record) {
record.set("parent", self);
});
This works fine, but when I’m creating a new record I’d rather not have to remember to include those 4 lines.
This answer says I can override the initialize method to take in additional parameters, but I’m not quite sure how I would get Backbone to automatically pass in the ParentModel to the overridden initialize method. Can anyone provide an example on how to do that?
I’ve heard of Backbone-relational which might help do what I want, but that’s another 23kb to include. If that’s the better way to go I’ll look at implementing it, but otherwise I’d prefer a simpler solution if one is available.
This needs to work whether I create a new ParentModel
record through code, or if it’s being automatically created by a JSON feed.
Solution
Answered By: Anonymous
I usually find that moving the structural elements out of the attributes is cleaner so my records and parent properties are on the object, not the attributes. That said, you could take advantage of the different events on the collection and the parent object:
var ParentModel = Backbone.Model.extend({
initialize: function () {
_.bindAll(this, 'adoptOne', 'adoptAll');
this.records = new Records();
this.on('change:records', function () {
this.records.reset(this.get('records'));
});
this.records.on('reset', this.adoptAll);
this.records.on('add', this.adoptOne);
this.records.reset(this.get('records'));
},
adoptAll: function () {
this.records.each(this.adoptOne);
},
adoptOne: function (model) {
model.parent = this;
}
});
A few tests :
var p = new ParentModel({
name: "I am the parent",
records: [{id: 1}, {id: 2}]
});
p.records.add({id: 3});
p.records.each(function (child) {
console.log(child.get('id')+' '+child.parent.get('name'));
});
p.set({records: [{id: 4}]});
p.records.each(function (child) {
console.log(child.get('id')+' '+child.parent.get('name'));
});
And a Fiddle http://jsfiddle.net/sPXaZ/