I'm using knockoutjs to visualize a tree. I have a initial AJAX-call to load the hole tree. Mapping happens using the knockout-mapping-plugin. Everything is working fine :) thanks for this great piece of software.
My problem is: I want to add additional observables to the model. I can do this using mapping options.
Object:
{ id: ko.observable(), parentID: ko.observable(), description: ko.observable(), children: ko.observableArray() }
Mappingoptions:
var mappingOptions = {
create: function (options) {
console.log("create");
var vm = ko.mapping.fromJS(options.data);
vm.newObservable = ko.observable(true);
return vm;
}
};
Mapping:
ko.mapping.fromJS(response, mappingOptions, self.nodes);
response is the list of objects(nodes). self.nodes is the observableArray() holding the list of objects(nodes)
Every node has the children-observalbeArray containing also nodes(with children) So nothing special, that's basically how a tree works :)
But this only adds this new observable to the root node. I want this extra observable also in every child and child's child (and so on...).
I tried:
var mappingOptions = {
create: function (options) {
console.log("create");
var vm = ko.mapping.fromJS(options.data);
vm.newObservable = ko.observable(true);
return vm;
},
'children': {
create: function (options) {
console.log("children.create");
options.data.newObservable = ko.observable(true);
return ko.mapping.fromJS(options.data);
}
}
};
I found this somewhere on the internet. It is not working.
Can someone help me?
Thanks!
P.S.: i can't provide a fiddle, because the service seems to be broken right know (or my firewall is blocking it :( )
I would try creating a data model. Let's call it Node
:
var Node = function Node(data) {
this.parentID = ko.observable( data.parentID );
this.description = ko.observable( data.description );
this.children = ko.observableArray([]);
data.children.forEach(function(child) {
this.children.push( new Node(child) );
}, this);
}
This makes it easy to create any additional properties on every node you wish.
In your viewmodel:
var Viewmodel = function Viewmodel() {
this.nodes = ko.observableArray([]);
this.getResponse = function getResponse() {
// response is loaded here
response.forEach(function(node) {
this.nodes.push( new Node(node) );
}, this);
};
}
Please note that I'm using the native Array.prototype.forEach
here. If you need to support IE < 9, you can replace it with Knockouts ko.utils.arrayForEach
instead.