Javascript 使用jquerydynatree和Knockout和Breeze

Javascript 使用jquerydynatree和Knockout和Breeze,javascript,knockout.js,breeze,dynatree,jquery-dynatree,Javascript,Knockout.js,Breeze,Dynatree,Jquery Dynatree,好的,根据PW Kad的建议,我将这部分问题从问题ID 17973991开始的地方分开 我有一个viewmodel,它利用围绕breeze构建的datacontext,它获取我想要的数据并填充可观察的数组。我需要使用Breeze已经检索到的数据来填充另一个(可观察的)数组,以便在treeview中使用 由于现有数据没有正确的字段名,我需要能够创建一个具有正确字段名的新数组,dynatree/fancytree插件可以使用该数组 我的第一次尝试:(后来证明不起作用,所以不要这样做!) 因此,在我的

好的,根据PW Kad的建议,我将这部分问题从问题ID 17973991开始的地方分开

我有一个viewmodel,它利用围绕breeze构建的datacontext,它获取我想要的数据并填充可观察的数组。我需要使用Breeze已经检索到的数据来填充另一个(可观察的)数组,以便在treeview中使用

由于现有数据没有正确的字段名,我需要能够创建一个具有正确字段名的新数组,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));
    });
};
然后,我在我的模块中添加了一个“AstreeMatterials”方法:

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 Papa的代码,谢谢John!) 注意:一旦我有了基础知识,就会有更多的代码进入“children”部分

最后将“激活”方法更改为使用新方法:

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
};
这意味着我不会再次点击服务器获取treeview版本的数据

编辑2。 根据PW Kad关于另一个问题(将很快添加到此问题中)的指导,我对“AstreeMatterials”方法进行了如下修改:

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);
};
我必须创建一个单独的新数组的原因(我认为)是我切片的现有可观察“材质”不包含正确的属性。Dynatree/fancytree需要(除其他外)一个“ID”和一个“名称”。我有ID,但在可观察的材质中有“materialName”,因此数组上的“$.each”是通过对可观察的材质进行切片创建的,以将“materialName”属性推送到我的新数组(tmpArray)中的“name”属性中。我对这一切都不熟悉,我可能有点离题了

我真的需要一个可观察的数组吗。。。?如果我了解可观测阵列的用途,我想我不会这么做。。。我的材料基本上是一成不变的,很少会改变。我想我可以简单地将“treeMaterials”作为一个标准的javascribt对象数组,并在viewmodel中返回它,而不是将其作为一个observableArray


无论哪种方式,当前materialname和ID的值都没有传递到我正在制作的tmpArray中的相关属性中。相反,我是从可观察的材质中获取函数,因此我认为我需要通过某种“展开”来获取实际值?

您没有填充树材质,因为在将其发送到AstreeMatterials时,材质中没有任何数据。我在这里做了一些假设,但基本上这就是你想要做的-

在视图模型的顶部,我假设您有两个可观察的耳环

var treeMaterials = ko.observableArray();
var materials = ko.observableArray();
对于activate方法,您需要获取一些数据,然后当datacontext返回承诺时,从中生成一棵对象类型的树-

var activate = function () {
    return datacontext.getMaterialPartials(materials).then(
            makeMyTree);
};
您不需要传递树材质或材质,因为它们已经在视图模型的范围内,并且您只是尝试用材质生成对象树

var makeMyTree = function () {
    treeMaterials([]);
    ko.utils.arrayForEach(materials(), function (mat) {
        treeMaterials.push(new treeMaterial(mat));
    });
};
这将生成具有可观察属性的对象的observableArray,这意味着如果要传递它们或试图获取它们的值,则需要使用类似treeMaterials()[0].name()的内容

以防您的dynatree无法获取可观测数据,或者无法很好地处理这些数据

我不确定dynatree或w/e如何处理可观测对象,因此这里是一个标准的不可观测对象数组,而不是一个可观测数组-

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));
    });
};

我很感激你的帮助,但还是有点不对劲。使用您的新代码,我最终在“treeMaterials”中得到了66个对象的数组(这是正确的),但是“id”和“name”都显示了“function dependentToServable(){…”的值如我所料,对象内的值设置为正确的值,但由于这不是敲除数组,我希望该值直接位于属性中,而不是像这样隐藏。是否确实不需要将材质的可观察值展开到非敲除数组中?可以使用data.name()为了得到name的值,当你知道如何打开itEasy时,它本质上是不容易的,不是吗?;-)所以我要做的唯一一件事就是让数组成为一个可观察的数组,否则html绑定将无法工作。这是很有道理的!非常感谢你的帮助,我今天学到了很多。