2013-08-05 4 views
0

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, который я делаю. Вместо этого я получаю функции от наблюдаемых материалов, поэтому я думаю, что мне нужно подойти к этому с помощью «разворота», чтобы получить фактические значения?

ответ

0

Вы не заселяете treeMaterials, потому что у вас нет данных в материалах, когда вы отправляете их в asTreeMaterials.Я делаю некоторые предположения здесь, но в основном это выглядит так, что вы пытаетесь сделать -

В верхней части модели представления, я полагаю, у вас есть два observableArrays

var treeMaterials = ko.observableArray(); 
var materials = ko.observableArray(); 

Для вашего метода активации вы должны пойти получить некоторые данные, а затем, когда ваш DataContext возвращает обещание, пойти сделать дерево из него какого-то типа объекта -

var activate = function() { 
    return datacontext.getMaterialPartials(materials).then(
      makeMyTree); 
}; 

Вам не нужно проходить treeMaterials или материалы, потому что они находятся в пределах масштаб модели представления уже, и вы просто пытаясь сделать дерево предметов из ваших материалов.

var makeMyTree = function() { 
    treeMaterials([]); 
    ko.utils.arrayForEach(materials(), function (mat) { 
     treeMaterials.push(new treeMaterial(mat)); 
    }); 
}; 

Это собирается сделать observableArray объектов с наблюдаемыми свойствами, то есть, если вы передаете их или пытаться получить их значение, которое вы должны использовать что-то вроде treeMaterials() [0] .name().

В случае, если ваш dynatree не принимает наблюдаемыми, или не очень хорошо играть с ними

Я не знаю, как ваш dynatree или ж/д работы с наблюдаемыми, так вот стандартный массив не наблюдаемые объекты вместо наблюдаемого массива -

var treeMaterials = []; 

var makeMyTree = function() { 
    treeMaterials[]; 
    ko.utils.arrayForEach(materials(), function (mat) { 
     treeMaterials.push(new treeMaterial(mat)); 
    }); 
}; 

var treeMaterial = function (data) { 
    var self = this; 

    self.name = data.name; 
    self.id = data.id; 
    self.children = []; 

    $.each(data.children, function (index, item) { 
     self.children.push(new Person(item)); 
    }); 
}; 
+0

Я ценю помощь, но что-то еще не так. Используя ваш новый код, я получаю массив из 66 объектов в «treeMaterials» (это правильно), но «id» и «name» обе показывают значения «function dependentObservable() {..." "_latestvalue" в пределах объект установлен на правильное значение, как я ожидал бы, но поскольку это не массив нокаутов, я бы ожидал, что значение будет прямо в свойстве, а не скрыто, как это. Вы уверены, что мне не нужно разворачивать наблюдаемые значения материалов в массив без нокаута? – TheMook

+0

Вы можете использовать data.name(), чтобы получить значение имени, которое по существу разворачивает его. –

+0

Легко, когда вы знаете, как это сделать? ;-) – TheMook

Смежные вопросы