Kendo UI MVVM和关联数组的难度

时间:2014-07-13 22:40:25

标签: javascript kendo-ui

我很难使用“关联数组”与Kendo UI的MVVM绑定视图模型。我试图将一个演示合并在一起,但是当我甚至没有一个半工作的演示时,真的很难。但这是我管理过的最好的......这是我的代码,还有一个jsBin来演示。它似乎不喜欢关联数组的想法,我不确定如何挂钩它。

关联数组的原因是因为我从数据库中提取了很多细节,但是它们需要在某些地方按名称调用。与其编写一堆搜索/排序方法相比,关联数组要简单得多。但是在我确实需要直接列出数据的一些地方,这给我带来了很多麻烦。

jsBin Demo

的Javascript

var viewModel = new kendo.data.ObservableObject({
  Id: "test/id",
  Associative: new kendo.data.ObservableArray([])
});

var array = viewModel.get("Associative");

array["One"] = { Id: "id/one" };
array["Two"] = { Id: "id/two" };
array["Three"] = { Id: "id/three" };

kendo.bind('body', viewModel);

HTML

<div data-bind="text: Id"></div>
<div data-template="display-associative-many" data-bind="source: Associative"></div>

<script type="text/x-kendo-template" id="display-associaite-many">
  <div>
    ${ data.Id }
  </div>
</script>

更新

我需要绑定的数据作为RavenDB存储在IDictionary<string, T>中,其中T是一种特定类型的对象(它有时会有所不同,所以我可以'给你一个具体的类型 - 也不是真的相关)

因此它存储在数据库中,如...

"Model" : {
   "ONE" : {
      "Id" : "id/one"
   },
   "TWO" : {
      "Id" : "id/two"
   },
   "THREE" : {
      "Id" : "id/three"
   }
}

显然有比这更多的数据,但目前这一切都是真正相关的。

虽然我具有改变它的物理能力,但它与该程序的许多其他部分相反。软件中的很多不同的地方已经在这个字典的前提下工作了。所以我会喜欢以避免在可能的情况下改变所有。如果这是真的,真的是让这项工作完全成功的唯一方法,我会做出改变。

我可以做的是在反序列化时进行一些映射。我现在的想法是将key分配给新属性Name,并尝试将kendo绑定到该属性。如果我的心理形象是正确的,那么数据就会变成......

Associative: [
   "One" : {
      Name: "One",
      Id: "id/one"
   },
   "Two" : {
     Name: "Two",
     Id: "id/two"
   },
   "Three" : {
     Name: "Three",
     Id: "id/three"
   }
]

如果我理解剑道的observable系统权利,那将会成为......

kendo.data.ObservableArray([
   kendo.data.ObservableObject,
   kendo.data.ObservableObject,
   kendo.data.ObservableObject
])

当我掌握它时,应该可以模拟绑定...对吗?

更新2

按照我自己的想法,我已经用这种方法做了一个有点成功的版本......但是,我不完全确定这是否安全或有效。我越来越关注表现。我仍在努力寻找其他方法来实现这一结果。

剑道模板

<script type="text/x-kendo-template" id="display-items-many">
        # for(var key in data) { #
        #   if (data.hasOwnProperty(key) && data[key].hasOwnProperty("Id")) { #
        <tr>
            <td>
                <strong>#= data[key].Id #</strong>
            </td>
            <td class="text-right">
                <code>#= data[key].Total #</code>
            </td>
        </tr>
        #   } #
        # } #
</script>

HTML

<table class="table borderless table-hover table-condensed" data-bind="source: Associative  data-template="display-items-many">

</table>

1 个答案:

答案 0 :(得分:2)

首先,您的模板名称错误:

data-template="display-associaitive-many"
           id="display-associaite-many"

其次,JavaScript数组不能像那样工作。

普通JS(没涉及剑道):

var array = [];
array["One"] = { Id: "id/one" };
array["Two"] = { Id: "id/two" };
array["Three"] = { Id: "id/three" };

array; // prints "[]"
array.length; // prints 0

关联数组应表示为对象http://www.laurencegellert.com/2012/01/associative-arrays-in-javascript/,然后您可以将其包装到Kendo ObservableObject中。但是,这意味着它实际上不是一个具有长度的数组,因此您无法将其绑定到Kendo ListView。

在我的头顶上,我能想到的唯一方法是将其表示为关联数组(对象)并将其绑定到ListView将是将ListView绑定到一个函数,然后将对象转换为阵列。虽然追踪变化有点奇怪......


回复您对原始帖子的评论和更新:

我正在键入这个我的头脑,所以如果你直接复制/粘贴它,如果它不起作用我很道歉,但假设你有一个数据源来填充数据,你可以使用{{1}将数据转换为实际数组的方法,如:

schema.parse

这个想法是,如果你的服务器返回了对象:

var _parseTheData = function (data) {
  var array = [];
  var item;
  for(var name in data) {
    item = data[name];
    item.Name = name;
    array.push(item);
  }
  return array;
};

var ds = new kendo.data.DataSource({
  transport: {
    read: {
      url: "http://wherever.com/theData"
    },
    schema: {
      parse: _parseTheData
    }
  }
});

然后解析函数会将其转换为数组:

{
   "ONE" : {
      "Id" : "id/one"
   },
   "TWO" : {
      "Id" : "id/two"
   },
   "THREE" : {
      "Id" : "id/three"
   }
}

然后,您可以将MVVM绑定到正常的小部件。例如ListLiew:

[
   {
      "Id" : "id/one",
      "Name" : "ONE"
   },
   {
      "Id" : "id/two",
      "Name" : "TWO"
   },
   {
      "Id" : "id/three",
      "Name" : "THREE"
   }
]