0

好的,根据 PW Kad 的建议,我将问题的这一部分从问题 ID 17973991 的开始位置分开。

我有一个视图模型,它利用围绕微风构建的数据上下文,它获取我想要的数据并填充可观察的数组。我需要使用 Breeze 已经检索到的数据来填充另一个(可观察的)数组以在树视图中使用。

由于现有数据没有正确的字段名,我需要能够使用 dynatree/fancytree 插件可以使用的正确字段名创建一个新数组。

我的第一次尝试:(随后显示不起作用,所以不要这样做!)

因此,在我的视图模型中,我在 .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 Papa 那里的编码大量借用,谢谢 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
};

意味着我不会再次访问服务器以获得数据的树视图版本。

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

(我认为)我必须创建一个单独的新数组的原因是我切片的现有“材料”可观察对象不包含正确的属性。Dynatree/fancytree 需要(除其他外)“ID”和“名称”。我有 ID,但我在可观察的材料中有“materialName”,因此通过切片可观察的材料创建的数组上的“$.each”将“materialname”属性推入新数组中的“name”属性(tmpArray)。我对这一切都很陌生,我可能在这里偏离了目标!

我真的需要一个可观察的数组......?如果我了解可观察数组的用途,我认为我不会这样做……我的材料几乎是一成不变的,并且很少会改变。我想我可以简单地将“treeMaterials”保留为标准的 javascrit 对象数组并在视图模型中返回它而不是使其成为 observableArray?

无论哪种方式,目前 materialname 和 ID 的值都没有传递到我正在制作的 tmpArray 中的相关属性中。相反,我从可观察的材料中获取功能,所以我认为我需要通过某种“展开”来获得实际值?

4

1 回答 1

0

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

在您的视图模型的顶部,我假设您有两个 observableArrays

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

对于您的激活方法,您需要获取一些数据,然后当您的数据上下文返回一个承诺时,从它中创建一个具有某种对象类型的树 -

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 不接受 observables,或者不能很好地处理它们

我不确定您的 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));
    });
};
于 2013-08-05T16:07:49.993 回答