【问题标题】:Accessing serialised dictionary data using knockout使用敲除访问序列化字典数据
【发布时间】:2016-04-14 21:49:37
【问题描述】:

我在使用 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)

我遇到的问题是在我看来访问此信息。我需要根据“键”值动态检索数据。我试过使用:

@{ 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"] 访问特定键的值。是否有可能使用淘汰赛来实现这一目标?

【问题讨论】:

  • options.items.Books?
  • 您发布的代码毫无意义。它充其量是不完整的,如果我想象完整的图片可能是怎样的,我会说你有一个关于创建observableArray 提供非数组的 KO 错误。请在您的代码中包含您的情况的完整重现(请参阅“minimal reproducible example”以获得指导)。

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


【解决方案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数组,其成员是通过索引访问的。 IE。上一个示例中的 items 对象是具有属性的对象,而不是 JavaScript 数组。

因此,在 ko 中,您需要使用 observables,如下所示:

var obs = ko.observable(items);

但是这个 observable 只会在整个 items 对象发生更改时通知更改,而不是在其任何属性(如 Books)被修改时通知更改。如果您需要在其中一些属性更改时获得通知(例如对视图进行 udpta),那么您需要使属性本身可观察,而不仅仅是根对象items。为此,您可以使用ko.mapping 插件,或手动执行。这相当于做:

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 之类的属性时通知您,那么在 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="value: items().Books().Type",在您使用 ko 映射或按照最后一个之前的代码块中的说明对其进行映射的情况。如果您需要更多信息,请阅读:When to use or not use parentheses with observables in data-binding expressions

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 2017-01-26
    相关资源
    最近更新 更多