使用knockout访问序列化的字典数据

时间:2016-01-10 15:21:34

标签: c# asp.net-mvc dictionary knockout.js

我在使用javascript访问序列化Dictionary<string, CustomType>中的数据时遇到了一些问题。以下json是我的序列化字典的输出。

生成的JSON是:

items: 
{
    "Books":{
        "Type":2,
        "Count":20547
    },
    "Games":{
        "Type":1,
        "Count":2647
    },
    "Films":{
        "Type":0,
        "Count":57213
    }
};

在我的javascript文件中,我创建了一个observable:

ko.observable(items)

我遇到的问题是在我的视图中访问此信息。我需要根据'key'值动态检索数据。我尝试过使用:

@{ var key = Model.Key; }
<p data-bind="text: items[@key].Count"></p>

但是,我收到以下错误:

Uncaught ReferenceError: Unable to process binding "text: function (){return items[Film].Count }"
Message: Film is not defined

使用c#,我可以使用items["Books"]访问特定密钥的值。是否有可能使用淘汰赛实现这一目标?

1 个答案:

答案 0 :(得分:1)

JavaScript objects表现得像关于如何访问其属性的字典(更确切地说是关联数组)。例如,这样做:

var items = {};
items.Books = { "Type":2, "Count":20547 };
items.Games = { "Type":1, "Count":2647 };

完全等同于:

var items = {};
items["Books"] = { "Type":2, "Count":20547 };
items["Games"] = { "Type":1, "Count":2647 };

当然,您也可以使用此语法来读取值:

var books = items["Books"];

只要在ko中使用它,就不能使用observableArray,因为它需要一个JavaScript数组,其成员可以通过索引访问。即前一个示例中的items对象是一个具有属性的对象,而不是JavaScript数组。

所以,在ko中你需要使用一个observables,如:

var obs = ko.observable(items);

但是这个observable只会在整个items对象发生更改时通知更改,而不会在修改任何属性(如Books时)。如果你需要在其中一些属性发生变化时收到通知(例如udpta视图),那么你需要自己观察属性,而不是根对象items。为此,您可以使用ko.mapping插件,也可以手动执行此操作。这相当于do:

var items = ko.observale({
    Books: ko.observable({
      Type: ko.observable(2), 
      Count: ko.observable(20547)
    }),
    Games:  ko.observable({
      Type: ko.observable(1), 
      Count: ko.observable(2647)
    })
});

在这种情况下,无论何时任何属性发生变化,都会收到通知。

但是,如果您在添加或转移某个属性BooksGames时需要通知yu,那么在ko中就没有直接的工作方式。您需要将对象映射到常规的可观察数组,并使ko.observableArray生效。映射可能是这样的:

var items = [
  { Name: 'Books', Type: 2, Count: 20547 },
  { Name: 'Games', Type: 1, Count: 2647 }
];

如果这样做,您可以创建一个可观察的数组。如果您仍然需要Name访问这些属性,则可以使用JavaScript方法(取决于浏览器支持的EcmaScript版本)或使用lodashunderscore等库,提供了访问和映射JavaScript对象和集合的强大方法。

注意:ko表达式能够检测到某些东西是可观察的,并展开其值。但是,如果需要访问可观察对象的observabe属性,则必须在所有级别使用括号,但最后使用括号,例如data-bind =&#34; value:items()。Books()。Type& #34;,如果你使用ko映射或映射它,就像在最后一个代码块之前的代码块中所解释的那样。如果您需要更多信息,请阅读:When to use or not use parentheses with observables in data-binding expressions