【问题标题】:How to use IEnumerable<ExpandoObject> in knockout.js?如何在 knockout.js 中使用 IEnumerable<ExpandoObject>?
【发布时间】:2013-10-05 09:28:54
【问题描述】:

问题描述

我想问一下如何在 knockout.js 中使用列表 Exbando 对象,我正在使用 Rob Conrey 的 Massive,所有返回的结果都是动态的,这对我来说很好,它适合我的需要,但是在将结果发送到淘汰赛时我就是不知道怎么处理。

目标

访问对象属性,如 obj.Name、obj.Brand 等...

示例代码

查看:

<div data-bind="foreach: Products">
    <p>Product name: <strong data-bind="text: Name"></strong></p>
</div>

控制器:

public JsonResult GetProducts() 
{
     Products products = new Products();
     var Model = products.GetAllProducts();
     return Json(Model, JsonRequestBehavior.AllowGet);
}

调用GetProducts的结果是:

[[{"Key":"Id","Value":1},{"Key":"Name","Value":"Badass Boots"},{"Key":"品牌"," Value":"Nike"},{"Key":"Description","Value":"能让你飞起来的超酷靴子(不是真的!)。"}等...]]

脚本文件:

function ProductListViewModel() {
    // Data
    var self = this;
    self.Products = ko.observableArray([]);

    $.getJSON("/Home/GetProducts", function (data) {
        self.Products(data);
    });
}

运行应用程序时出现 JavaScript 错误:

未捕获的 ReferenceError:无法解析绑定。绑定值:文本:名称消息:名称未定义

屏幕截图 1:

屏幕截图 2:

【问题讨论】:

  • 那么这里有什么不合适的?
  • 我收到此错误消息:未捕获的 ReferenceError:无法解析绑定。绑定值:文本:名称消息:名称未定义

标签: c# asp.net-mvc-3 knockout.js expandoobject massive


【解决方案1】:

一般来说,ExpandoObject 是出于所有意图和目的,是一本字典。当在此处序列化为 JSON 时,它被视为字典并成为键/值对的集合(并非所有序列化程序都以这种方式运行,但您正在使用的序列化程序会这样做)。它不是您可以通过名称访问成员的对象,您必须将其转换为您可以的表示形式(或首先将其序列化为一个表示形式)。

进行转换并不是世界上最糟糕的事情:

function Product(item) {
    var self = this;
    // assuming item is an array of key/value pairs
    ko.utils.arrayForEach(item, function(pair) {
        // doesn't necessarily have to be mapped as an observable
        self[pair.Key] = ko.observable(pair.Value);
    });
}

这样,您就可以将结果映射到您的产品数组:

$.getJSON("/Home/GetProducts", function (data) {
    self.Products(ko.utils.arrayMap(data, function(item) {
        return new Product(item);
    }));
});

【讨论】:

  • 我不知道序列化在 ASP.net 中是如何工作的,或者它是否可以配置。但我通常使用Json.NET 来满足我所有的 JSON 需求,它将字典序列化为对象,而不是键/值对的幼稚集合。也许你可以在这里使用 Json.NET...我只是不知道如何设置它。
【解决方案2】:

看起来问题是因为您试图将 ko.observableArray 的值设置为 json 数组。不确定这是否可行。通常我会这样做:

function ProductListViewModel() {
   // Data
   var self = this;
   self.Products = ko.observableArray([]);

   $.getJSON("/Home/GetProducts", function (data) {
       ko.utils.arrayForEach(data, function(item) {
           self.Products.push({
               Name : item.Name
           });
       });
   });

}

使用 knockout 的 arrayForEach 函数遍历您的 json 数组,并将每个对象推送到您的 observableArray。

【讨论】:

  • 我做到了,我也得到了未捕获的 ReferenceError: Unable to parse bindings。绑定值:文本:名称消息:名称未定义
  • 您能否发布 Products c# 类是什么。查看您从服务器返回的 JSON,有些东西看起来不太正确。您在数组中有一个数组,并且您的每个 Product 类属性都是对象,这似乎不正确。我认为您的产品看起来更像这样:{ 'Id' : '1', 'Name' : 'BadAss Boots' }。您集合中的每个产品都是一个具有一些属性的 Json 对象。
  • 感谢您的帮助非常感谢:);
【解决方案3】:

在您的 JSON 中,我看到了 KeyValue 的序列,因此您必须指定敲除必须查询的文件名才能获取相对值并将其放在屏幕上。

所以将&lt;strong data-bind="text: Name"&gt; 更改为&lt;strong data-bind="text: Key"&gt;,这应该对你有用。

【讨论】:

    猜你喜欢
    • 2015-05-06
    • 1970-01-01
    • 2012-09-22
    • 2011-10-31
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多