2

ノックアウト製本で表示されたアイテムリストがあります。簡略化すると、次のようになります。

<ul data-bind="foreach: currentItems ">
    <li>
        <div>
            <span data-bind="text: Heading"></span>
        </div>
   </li>
</ul>

選択リストには、最初のリストに追加できる潜在的なアイテムがあります。値がダブルクリックされると、selectedItem で ajax 呼び出しが開始されます。

<select id="lstSongs" data-bind="options: possibleItems, optionsText: 'Heading', value: selectedItem, dblclick: $root.addItem"></select>

どちらの配列も、サーバーで定義された同じモデル構造を使用します。

ビューモデルは次のようになります。

function MyViewModel() {
    var self = this;
    self.currentItems = ko.observableArray([]);
    self.possibleItems = ko.observableArray([]);
    self.selectedItem = ko.observable();

    self.addItem = function(item) {
        $.ajax({
            type: "POST",
            url: "/api/MyController/AddItem",
            contentType: "application/json",
            dataType: "json",
            data: ko.toJSON(item),
            success: function(itemId) {

                // Attempt1
                alert(itemId);
                item.ItemId(itemId);
                alert("hello1");
                alert(item.ItemId);
                currentItems.push(item);

                // Attempt2
                alert(itemId);
                item.ItemId = itemId;
                alert("hello2");
                alert(item.ItemId);
                currentItems.push(item);

                // Attempt3
                alert(itemId);
                selectedItem.ItemId = itemId;
                alert("hello3");
                alert(selectedItem.ItemId);
                currentItems.push(selectedItem);
            }
        });
    };
}

var viewModel = new MyViewModel();
var data = @Html.Raw(new JavaScriptSerializer().Serialize(Model));
ko.mapping.fromJS(data, {}, viewModel);
ko.applyBindings(viewModel);

currentItems を含むリストは、ko.mapping を使用して MVC 初期モデルからロードされます。possibleItems には、動的な ajax 呼び出しからの値が読み込まれます。しかし、両方とも期待どおりにロードされているので、それらのバインディングは問題ないと思います。

ダブルクリックは期待どおりにトリガーされます。サーバーで呼び出しが検出され、適切な itemId が返されます。正常に返された場合、その値を selectedItem に設定する必要があります。次に、selectedItem を currentItems 配列に追加し、最初のリストに表示する必要があります。

私はいくつかの試みで詳しく説明しましたが、成功しませんでした。私はそれらを一度に1つずつ試し、他の人がコメントしました。

Attempt1: itemId は返されますが、最初の hello に到達していません。なんで?それは観察可能なプロパティを設定する方法ではありませんか?

Attempt2: 値が設定され、hello2 が表示され、itemId が設定されていることが報告されました。ただし、プッシュ呼び出しでは、項目が currentItem リストに表示されません。

Attempt3: 同じアプローチですが、今回はビューモデルの selectedItem にプロパティが設定されています。今回は hello3 に到達していません。

4

4 に答える 4

2

itemおそらくオブザーバブルではなく値として渡されているため、最初の試みは機能していません。

2 回目の試みはうまくいくはずですが、次のself変数を使用する必要があります。

self.currentItems.push(item);

3 回目の試行は、1 回目の試行と同じ理由で機能しません。

于 2013-08-27T00:56:46.127 に答える
1

追加したアイテムのインスタンスを作成し、それに応じて selectedItem および currentItems 配列に割り当てる必要があります

success: function() {    
    var addedItem = new Item {ItemId:item.ItemId,Heading:item.Heading };
    self.selectedItem(addedItem);
    self.currentItems.push(addedItem);
    alert("Successfully added");   
}
于 2013-08-26T22:56:56.883 に答える
1

Bradley Trager は、彼の最初の提案で私を正しい軌道に乗せました。他の誰かを助けるために、ここに実用的なソリューションを追加するだけです:

var addedItem = ko.mapping.fromJSON(ko.toJSON(item));
addedItem.ItemId(itemId);
self.currentItems.push(addedItem);
于 2013-08-27T21:17:50.687 に答える
0

問題を再現できると思います。あなたの問題は、代わりにsselectでイベントをトリガーしたいの (ダブル) クリックにデータバインドしていることです。そうでない場合は、これを見ることができますが、代わりに: 関数に渡されているのはルート ビューモデルです。optionalert(itemId)console.log(item)

2 つの解決策が思い浮かびます。

于 2013-08-26T22:25:25.767 に答える