在 Knockout 和 Breeze 中使用 jQuery dynatree [英] Using jQuery dynatree with Knockout and Breeze

查看:17
本文介绍了在 Knockout 和 Breeze 中使用 jQuery dynatree的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,按照 PW Kad 的建议,我将这部分问题从问题 ID 17973991 的开始处分开.

OK, following the suggestion from PW Kad I'm splitting this part of the question off from where it started on question ID 17973991.

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

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.

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

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!)

所以在我的视图模型中,我在 .js 文件的顶部添加了以下内容:

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

然后我在我的模块中添加了一个asTreeMaterials"方法:

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

(大量借用 John Papa 在那里的编码,感谢 John!)注意:一旦我掌握了基础知识,就会有更多的代码进入儿童"部分

(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

最后将activate"方法更改为使用新方法:

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.

编辑 2.按照 PW Kad 对另一个问题的指导(很快将添加到这个问题中),我修改了asTreeMaterials"方法如下:

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

我必须创建一个单独的新数组的原因(我认为)是我切片的现有材料"可观察对象不包含正确的属性.Dynatree/fancytree 需要(除其他外)一个ID"和一个名称".我有 ID,但我在材料 observable 中有materialName",因此数组上的$.each"由可观察的材料切片创建,以将materialname"属性推入我的新数组中的name"属性(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!

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

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?

无论哪种方式,目前 materialname 和 ID 的值都不会传递到我正在制作的 tmpArray 中的相关属性中.相反,我是从可观察的材料中获取函数,所以我认为我需要通过某种展开"来解决这个问题以获得实际值?

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?

推荐答案

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

You are not populating the treeMaterials because you don't have any data in materials when you are sending it to asTreeMaterials. I am making some assumptions here but basically it looks like this is what you are trying to do -

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

At the top of your view model, I assume you have two observableArrays

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

对于你的 activate 方法,你需要去获取一些数据,然后当你的 datacontext 返回一个承诺时,去用某种对象类型制作一棵树 -

For your activate method, you need to go get some data, and then when your datacontext returns a promise, go make a tree out of it of some object type -

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

您不需要传递 treeMaterials 或材料,因为它们已经在视图模型的范围内,而您只是想用您的材料制作对象树.

You don't need to pass treeMaterials or materials because they are within the scope of the view model already, and you are just trying to make a tree of objects out of your materials.

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

这将创建一个具有 observable 属性的 observableArray 对象,这意味着如果您正在传递它们或试图获取它们的值,您将需要使用类似 treeMaterials()[0].name() 的东西.

This is going to make an observableArray of objects with observable properties, meaning if you are passing them or trying to get their value you would need to use something like treeMaterials()[0].name().

如果你的 dynatree 不接受 observables,或者不能很好地使用它们

我不确定你的 dynatree 或 w/e 是如何与 observables 一起工作的,所以这里是一个标准的非 observable 对象数组而不是一个 observable 数组 -

I am not sure how your dynatree or w/e works with observables, so here is a standard array of non-observable objects instead of an observable array -

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

这篇关于在 Knockout 和 Breeze 中使用 jQuery dynatree的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆