1

仮想要素のプロパティをグリッドにリストしているときに、ノックアウトの foreach バインディングに問題があります。

Web API は期待どおりに JSON データを返しますが、ノックアウトは仮想要素のプロパティを正しく表示していません。

私の UI には製品のリストが表示され、その列の 1 つがProductCategory.Name. 何らかの理由で、各製品カテゴリの初登場のみが表示されます。

名前 カテゴリー

Pr01 Cat01
Pr02        
Pr03 カテゴリ02
Pr04 カテゴリ03
Pr05        

2番目と5番目の製品も「Cat01」カテゴリの製品です。しかし、何らかの理由で、それらには表示されません。

私は次のモデルを持っています:

public class Product
{
    [ScaffoldColumn(false)]
    public int ProductId { get; set; }

    public string Name { get; set; }
    public int ProductsCategoryId { get; set; }

    public virtual ProductsCategory ProductCategory { get; set; }
}

public class ProductsCategory
{
    public int ProductsCategoryId { get; set; }

    public string Name { get; set; }
}

これは私がグリッドをバインドする方法です:

<tbody data-bind="foreach: products">
    <tr>            
        <td class="left" data-bind="text: $data.Name"></td>
        <td class="left" data-bind="text: $data.ProductCategory.Name"></td>
    </tr>
</tbody>

これが JSON です。

[{
    "$id": "1",
    "ProductCategory": {
        "$id": "2",
        "ProductsCategoryId": 1,
        "Reference": "OSOL                            ",
        "Name": "Óculos de Sol",
        "ProductsCategoryStatusId": 1
    },
    "ProductId": 3,
    "Reference": "HTHTOD                          ",
    "BarCode": "2122071530085                   ",
    "Name": "Thin Hard Trivex OD",
    "Description": null,
    "ProductsBrandId": 1,
    "ProductsCategoryId": 1,
    "ProductsSupplierId": 1,
    "ProductStatusId": 1
}, {
    "$id": "3",
    "ProductCategory": {
        "$ref": "2"
    },
    "ProductId": 4,
    "Reference": "HTHTOE                          ",
    "BarCode": "2122071531163                   ",
    "Name": "Thin Hard Trivex OE",
    "Description": "null",
    "ProductsBrandId": 1,
    "ProductsCategoryId": 1,
    "ProductsSupplierId": 1,
    "ProductStatusId": 1
}, {
    "$id": "4",
    "ProductCategory": {
        "$id": "5",
        "ProductsCategoryId": 2,
        "Reference": "OGRAU                           ",
        "Name": "Óculos de Grau",
        "ProductsCategoryStatusId": 1
    },
    "ProductId": 10,
    "Reference": "HTHTOX                          ",
    "BarCode": "2123180206342                   ",
    "Name": "Thin Hard Trivex OX",
    "Description": null,
    "ProductsBrandId": 2,
    "ProductsCategoryId": 2,
    "ProductsSupplierId": 1,
    "ProductStatusId": 1
}, {
    "$id": "6",
    "ProductCategory": {
        "$id": "7",
        "ProductsCategoryId": 3,
        "Reference": "LNTS                            ",
        "Name": "Lentes",
        "ProductsCategoryStatusId": 1
    },
    "ProductId": 16,
    "Reference": "HTHTOY                          ",
    "BarCode": "2123192208431                   ",
    "Name": "Thin Hard Trivex OY",
    "Description": null,
    "ProductsBrandId": 4,
    "ProductsCategoryId": 3,
    "ProductsSupplierId": 1,
    "ProductStatusId": 1
}, {
    "$id": "8",
    "ProductCategory": {
        "$ref": "2"
    },
    "ProductId": 12,
    "Reference": "HTHTOZ                          ",
    "BarCode": "2123192059538                   ",
    "Name": "Thin Hard Trivex OZ",
    "Description": null,
    "ProductsBrandId": 1,
    "ProductsCategoryId": 1,
    "ProductsSupplierId": 1,
    "ProductStatusId": 1
}]

ご覧のとおり、ProductsCategoryデータは一度表示されると、同じカテゴリの次の製品によって参照されます。

グリッド上のすべての要素のカテゴリ名を表示するためにこれを修正する方法について何か提案はありますか?

4

2 に答える 2

0

ProductCategoryID からオブジェクトのマッピングを作成する必要があります。そうすれば、カテゴリをレンダリングするときに、マップから適切なカテゴリを取得できます。

参照が解決される製品をマップするか、オンデマンドでそれらの参照を解決する関数を作成できます。この例では、後者のアプローチを選択しました。

function ViewModel(data) {
    var self = this,
        productCategories = function (products) {
            var map = {};
            // throw all categories (with ids) into the map
            ko.utils.arrayForEach(products, function (item) {
                var category = item.ProductCategory;
                if (category.$id) map[category.$id] = category;
            });
            return map;
        } (data.products);

    self.products = ko.observableArray(data.products);

    self.getProductCategory = function (product) {
        var productCategory = product.ProductCategory,
            ref = productCategory.$ref;
        // get the referenced category
        if (ref) productCategory = productCategories[ref];
        return productCategory;
    }
}

次に、次のようにバインドします。

<tbody data-bind="foreach: products">
    <tr>            
        <td class="left" data-bind="text: Name"></td>
        <td class="left" data-bind="text: $root.getProductCategory($data).Name"></td>
    </tr>
</tbody>

デモ

于 2012-11-16T05:12:21.100 に答える
0

あなたの json は、ノックアウトが理解できない形式です。製品カテゴリは 1 回だけ送信されます。製品カテゴリが 2 回目に送信されると、最初のカテゴリへの「参照」が含まれます。

以下の id:3 のオブジェクトを参照してください (問題の例)。

"$id":"3",
"ProductCategory":{"$ref":"2"}

以下の詩は正しいです。

"$id":"1",
"ProductCategory":{"$id":"2","ProductsCategoryId":1,"Reference":"OSOL ","Name":"Óculos de Sol","ProductsCategoryStatusId":1}

更新: 上記の非標準の json を処理する方法。

サンプルプロジェクトを見てみました。\ProductStore\App_Start\WebApiConfig.cs に次のものがあります。

var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling =
                Newtonsoft.Json.PreserveReferencesHandling.Objects;

これによると、http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization、オブジェクト参照を保持すると、ほとんどの場合使用できない非標準のjsonが生成されますクライアント。

ノックアウトが機能するようにする標準の json を取得します。

var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling =
                Newtonsoft.Json.PreserveReferencesHandling.None;  //this needs to be None
于 2012-11-16T02:24:34.437 に答える