0

サーバーから特定の JSON を取得し、ネストされた配列 (バリアント リスト、バリアント、および列) でアイテムを追加/編集/削除できるようにしたいのですが、knockout.js でそれを行う方法がわかりません。

そのJSONオブジェクトのプロパティをオブザーバブルに変更する必要があることを知っています.「バインディング」の下に示されているようなマッピングプラグインを使用してそれを行い、すべての値が正しくバインドされています-しかし、入力フィールドの値を変更すると、モデル/view は自動的に更新されません。

なんで?何か不足していますか?

では、ネストされた配列は、独自のコードを記述する必要なく、knockout.js によってネイティブにサポートされているのでしょうか? このJSONを完全に機能するknockout.jsビューモデルにするにはどうすればよいですか?

現在利用可能なバージョン (ノックアウト: v2.1.0、マッピング プラグイン: v2.3.2) を使用します。

JSON

{
    "VariantList": [
        {
            "ColumnCount": 1,
            "Variants": [
                {
                    "Title": "One column 100%",
                    "Columns": [
                        "100 %"
                    ]
                }
            ]
        },
        {
            "ColumnCount": 2,
            "Variants": [
                {
                    "Title": "Two columns 50%/50%",
                    "Columns": [
                        "50%",
                        "50%"
                    ]
                },
                {
                    "Title": "Two columns 75%/25%",
                    "Columns": [
                        "75%",
                        "25%"
                    ]
                }
            ]
        }
    ]
}

HTML

<div data-bind="foreach: VariantList">
    <h2 data-bind="text: ColumnCount"></h2>
    <div data-bind="foreach: Variants">
        <h3 data-bind="text: Title"></h3>
        <table style="width:500px">
            <tr>
                <!-- ko foreach: Columns -->
                <th><input data-bind="value: $data"/></th>
                <!-- /ko -->
            </tr>
            <tr>
                <!-- ko foreach: Columns -->
                <td data-bind="style: {width:$data}, text:$data"></td>
                <!-- /ko -->
            </tr>
        </table>
   </div>
</div>

バインディング

var viewModel;
$(function(){
   viewModel = ko.mapping.fromJS(myJson);
   ko.applyBindings(viewModel);
});
4

1 に答える 1

2

問題は、マッピングプラグインがデフォルトで配列内のプリミティブ値をオブザーバブルに変換しないことです。それでも$data、入力に対してバインドするときまでに、観察可能な値ではなく、ラップされていない値が得られます。

これを機能させる最も簡単な方法は、データを次のように構造化することです。

var data = {
    "VariantList": [
        {
            "ColumnCount": 1,
            "Variants": [
                {
                    "Title": "One column 100%",
                    "Columns": [
                        { value: "100 %" }
                    ]
                }
            ]
        },
        {
            "ColumnCount": 2,
            "Variants": [
                {
                    "Title": "Two columns 50%/50%",
                    "Columns": [
                        { value: "50%" },
                        { value: "50%" }
                    ]
                },
                {
                    "Title": "Two columns 75%/25%",
                    "Columns": [
                        { value: "75%" },
                        { value: "25%" }
                    ]
                }
            ]
        }
    ]
};

value次に、のループでバインドしますColumns。サンプルは次のとおりです:http://jsfiddle.net/rniemeyer/MCnMX/

この構造でデータを取得できない場合は、マッピングオプションを使用して、このような構造に変換することを検討できます。サンプルは次のとおりです:http://jsfiddle.net/rniemeyer/sH3r2/

var mappingOptions = {
    Columns: {
        create: function(options) {
            return { value: ko.observable(options.data) };  
        }
    }        
};

var viewModel = ko.mapping.fromJS(data, mappingOptions);

JSONを受け取ったのと同じ形式でサーバーに送り返す必要がある場合は、いくつかのオプションがあります。私はこのようにするのが好きです:http ://www.knockmeout.net/2011/04/controlling-how-object-is-converted-to.html 。データのサンプルは次のとおりです:http://jsfiddle.net/rniemeyer/Eed2R/

var Value = function(val) {
    this.value = ko.observable(val);  
};

Value.prototype.toJSON = function() {
    return ko.utils.unwrapObservable(this.value);  
};

var mappingOptions = {
    Columns: {
        create: function(options) {
            return new Value(options.data);
        }
    }        
};

var viewModel = ko.mapping.fromJS(data, mappingOptions);
于 2012-09-03T13:57:38.763 に答える