I have a problem with knockout.js and the mapping plugin does not create models for child arrays in the source data
var data = { outer: [ { 'id': 1, name: 'test outer', inner: [{ 'id': 1, name: 'test inner'}]}] }; function OuterModel(data) { var self = this; ko.mapping.fromJS(data, {}, this); self.fullText = ko.computed(function() { return self.id() + ". " + self.name(); }); } function InnerModel(data, parent) { var self = this; ko.mapping.fromJS(data, {}, this); self.fullText = ko.computed(function() { return self.id() + ". " + self.name() + "(" + parent + ")"; }); } function PageModel() { var self = this; this.data = null; } var mapping = { 'outer': { key: function(data) { return ko.utils.unwrapObservable(data.id); }, create: function(options) { var thisModel = new OuterModel(options.data); return thisModel; } }, 'inner': { key: function(data) { return ko.utils.unwrapObservable(data.id); }, create: function(options) { var thisModel = new InnerModel(options.data); return thisModel; } } }; var model = new PageModel(); model.data = ko.mapping.fromJS(data, mapping);
(This is a small repo I can do for this. Fiddle is available here: http://jsfiddle.net/msieker/6Wx3s/ )
In short, the InnerModel constructor is never called. I tried this with 'InnerModel'
both where it is in this snippet and within the 'inner'
display. From most posts that I saw, this should work, but obviously I am missing something.
Anyone have experience with this that can point me in the right direction?
EDIT: Based on @John Earles answer, I got this a little closer to what I need:
var data = { outer: [ { 'id': 1, name: 'test outer', inner: [{ 'id': 1, name: 'test inner'}]}] }; var outerMapping = { 'outer': { key: function(data) { return ko.utils.unwrapObservable(data.id); }, create: function(options) { var thisModel = new OuterModel(options.data); return thisModel; } } }; function OuterModel(data) { var self = this; ko.mapping.fromJS(data, innerMapping, this); self.fullText = ko.computed(function() { return self.id() + ". " + self.name(); }); } var innerMapping = { 'inner': { key: function(data) { return ko.utils.unwrapObservable(data.id); }, create: function(options) { console.log(options); var thisModel = new InnerModel(options.data, options.parent()); return thisModel; } } }; function InnerModel(data, parent) { var self = this; ko.mapping.fromJS(data, {}, this); self.fullText = ko.computed(function() { return self.id() + ". " + self.name() + "(" + parent + ")"; }); } function PageModel() { var self = this; this.data = null; } var model = new PageModel(); model.data = ko.mapping.fromJS(data, outerMapping); ko.applyBindings(model);?
However, the parent
that is passed to InnerModel is null
, and this causes me to chase the mapping plugin. The docs make me think that this should be passed in the options
parameter to the create
function, but instead I get an observable
whose value is null
. Any additional pointers in this direction?