OK, following the suggestion from PW Kad I'm splitting this part of the question off from where it started on question ID 17973991.
I have a viewmodel that utilises a datacontext built around breeze and it fetches the data I want and populates observable arrays. I have a requirement to use data already retrieved by Breeze to populate another (observable) array to use in a treeview.
As the existing data does not have the correct fieldnames, I need to be able to create a new array with correct fieldnames that the dynatree/fancytree plugin can use.
My first attempt: (subsequently shown to not work so don't do this!)
So in my viewmodel I added the following at the top of the .js file:
var treeMaterials = ko.observableArray();
var treeMaterial = function (data) {
var self = this;
self.name = ko.observable(data.name);
self.id = ko.observable(data.id);
self.children = ko.observableArray();
$.each(data.children, function (index, item) {
self.children.push(new Person(item));
});
};
I then added an "asTreeMaterials" method to my module:
var asTreeMaterials = function (treeMatsObservable, matsObservable) {
treeMatsObservable([]); //clear out array as we're rebuilding it in here
var tmpArray = treeMatsObservable(); //create local temp array to avoid ko notifications on each push
$.each(matsObservable, function (index, mat) {
tmpArray.push(new treeMaterial({
id: mat.id,
name: mat.materialName,
children: []
}));
});
treeMatsObservable(tmpArray);
};
(borrowing heavily from John Papa's coding there, thanks John!) Note: there will be more code going into the "children" bit once I have the basics working
And finally changing the "activate" method to use the new method:
var activate = function () {
// go get local data, if we have it
return datacontext.getMaterialPartials(materials),
asTreeMaterials(treeMaterials, materials);
};
....
and then returning the new array from the module:
var vm = {
activate: activate,
materials: materials,
treeMaterials: treeMaterials,
title: 'My test app page 1',
refresh: refresh
};
means that I don't hit the server again for the treeview version of the data.
Edit 2. Following the guidance from PW Kad on the other question (will be added to this question shortly) I have modified the "asTreeMaterials" method as follows:
var asTreeMaterials = function () {
treeMaterials([]); //clear out array as we're rebuilding it in here
var matArray = materials().slice();
var tmpArray = [];
$.each(matArray, function (index, mat) {
tmpArray.push(new treeMaterial({
id: mat.id,
name: mat.materialName,
children: []
}));
});
treeMaterials(tmpArray);
};
The reason (I think) I have to create a separate new array is that the existing "materials" observable that I slice does not contain the correct properties. Dynatree/fancytree requires (among other things) an "ID" and a "name". I have the ID, but I have "materialName" in the materials observable hence the "$.each" on the array created by the slicing of the materials observable to push the "materialname" property into the "name" property in my new array (tmpArray). I'm new to all this, I may be miles off the mark here!
Do I actually need an observable array...? I don't think I do if I understand what observable arrays are for... my materials are pretty much set in stone and will change very, very rarely. I presume I can simply leave "treeMaterials" as a standard javascribt object array and return that in the viewmodel instead of making it an observableArray?
Either way, currently the values for materialname and ID are not passed into the relevant properties in the tmpArray I'm making. Instead I'm getting the functions from the materials observable so I think I need to approach this with an "unwrap" of some sort to get at the actual values?