OK, в соответствии с предложением от PW Kad Я раскалываю эту часть вопроса прочь от того, где он начал на вопрос ID 17973991.Использование JQuery dynatree с Knockout и Breeze
У меня есть ViewModel, который использует DataContext встроенного вокруг бриза, и он извлекает данные, которые я хочу, и заполняет наблюдаемые массивы. У меня есть требование использовать данные, уже полученные Breeze, для заполнения другого (наблюдаемого) массива для использования в древовидной структуре.
Поскольку существующие данные не имеют правильных имен полей, мне нужно иметь возможность создавать новый массив с правильными именами полей, которые может использовать плагин dynatree/fancytree.
Моя первая попытка: (! Впоследствии показано, не работает, так что не делать этого)
Так что в моем ViewModel я добавил следующее в верхней части .js файла:
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));
});
};
затем я добавил метод «asTreeMaterials» для моего модуля:
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);
};
(заимствуя от John папина кодирования там, спасибо Джона!) Примечания: там будет больше коды происходит в бит «дети», как только у меня есть основы работы
И, наконец, изменяя способ «активировать», чтобы использовать новый метод:
var activate = function() {
// go get local data, if we have it
return datacontext.getMaterialPartials(materials),
asTreeMaterials(treeMaterials, materials);
};
....
, а затем вернувшихся новый массив из модуля:
var vm = {
activate: activate,
materials: materials,
treeMaterials: treeMaterials,
title: 'My test app page 1',
refresh: refresh
};
означает, что я снова не попал на сервер для версии данных дерева.
Edit 2. После указания от PW Kad на другой вопрос (будет добавлено к этому вопросу в ближайшее время) я модифицировал метод «asTreeMaterials» следующим образом:
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);
};
Причина (я думаю,) Я должен создать отдельный новый массив, так это то, что существующие «материалы» наблюдаемые, что I slice не содержат правильных свойств. Dynatree/fancytree требует (среди прочего) «ID» и «имя». У меня есть идентификатор, но у меня есть «materialName» в наблюдаемых материалах, следовательно, «$ .each» в массиве, создаваемом обработкой материалов, которые можно наблюдать, чтобы надавить свойство «materialname» на свойство «name» в моем новом массиве (tmpArray). Я новичок во всем этом, я могу быть в милях отсюда!
Действительно ли мне нужен наблюдаемый массив ...? Я не думаю, что я это сделаю, если пойму, какие наблюдаемые массивы для ... мои материалы в значительной степени заложены в камне и очень сильно изменятся. Я полагаю, я могу просто оставить «treeMaterials» в качестве стандартного массива объектов javascribt и вернуть его в viewmodel вместо того, чтобы сделать его наблюдаемым массивом?
В любом случае, в настоящее время значения для имени материала и идентификатора не передаются в соответствующие свойства в tmpArray, который я делаю. Вместо этого я получаю функции от наблюдаемых материалов, поэтому я думаю, что мне нужно подойти к этому с помощью «разворота», чтобы получить фактические значения?
Я ценю помощь, но что-то еще не так. Используя ваш новый код, я получаю массив из 66 объектов в «treeMaterials» (это правильно), но «id» и «name» обе показывают значения «function dependentObservable() {..." "_latestvalue" в пределах объект установлен на правильное значение, как я ожидал бы, но поскольку это не массив нокаутов, я бы ожидал, что значение будет прямо в свойстве, а не скрыто, как это. Вы уверены, что мне не нужно разворачивать наблюдаемые значения материалов в массив без нокаута? – TheMook
Вы можете использовать data.name(), чтобы получить значение имени, которое по существу разворачивает его. –
Легко, когда вы знаете, как это сделать? ;-) – TheMook