使用带有Knockout和Breeze的jQuery dynatree [英] Using jQuery dynatree with Knockout and Breeze

查看:74
本文介绍了使用带有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.

我有一个viewmodel,利用围绕微风建立的datacontext,它获取我想要的数据并填充可观察数组。我需要使用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!)

所以在我的viewmodel中,我在.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

最后更改激活方法以使用新方法:

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!

我真的需要一个可观察的阵列......?如果我理解可观察阵列的用途,我认为我不会这样做......我的材料几乎是一成不变的,而且很少会发生变化。我假设我可以简单地将treeMaterials作为标准的javascribt对象数组并将其返回到viewmodel而不是使其成为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();

对于你的激活方法,你需要获取一些数据,然后当你的datacontext返回一个promise时,从某种对象类型中取出一棵树 -

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

这将使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不带观察者,或者与他们玩得不好

我不确定你的dynatree或w / e如何与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天全站免登陆