6

これは誰かにとって簡単な答えになると確信しています。私は次のViewModelを持っています:

@{
    var initialData = new JavaScriptSerializer().Serialize(Model);
}
var data = @Html.Raw(initialData);
function ViewModel(data) {
    var self = this;
    self.Name = ko.observable(data.Name);
    self.Items = ko.observableArray(data.Items);
    self.addItem = function() { self.Items.push(""); };
    self.removeItem = function(data) { self.Items.remove(data); }
}
$(document).ready(function() {ko.applyBindings(new ViewModel(data)); });

そして次のビュー:

<div>
    Name: <span data-bind="text: Name"></span>
</div>
<div>
    Items: <button data-bind="click: addItem">Add Item</button>
</div>
<div>
    <table>
        <tbody data-bind="template: { name: 'itemTemplate', foreach: Items }"></tbody>
    </table>
</div>
<script type="text/html" id="itemTemplate">
    <tr>
        <td>
            <input data-bind="value: $data" />
            <a href="#" data-bind="click: function() {$parent.removeItem($data)}">Remove Item</a>
        </td>
    </tr>
</script>

を除いて、すべてが正しく機能しているようですremoveItem。新しい行が追加され、空の新しい行で[アイテムの削除]をクリックすると、新しい行がすべて削除されます。私はこれを機能させるためにたくさんのノックアウトチュートリアルを見てきました、そして私の方法は有効な試みのようです、しかし明らかに...私は何かを逃しているに違いありません。助言がありますか?

4

1 に答える 1

14

observableArrayのremove関数は配列をループし、渡された値に一致する項目をすべて削除します。あなたの場合、文字列を扱っているだけで、新しい文字列(値なし)がすべて「」に一致することがわかります。

それを処理するいくつかの方法があります:

  • のような文字列だけでなく、オブジェクトを処理することもできます{ value: ko.observable("") }。次に、渡す$dataと、そのオブジェクト参照に一致する実際のアイテムのみが削除されます。値が監視可能でなく、データ自体(プロパティではない)である場合、書き込みによって実際にビューモデルに戻ることはありません。

  • それがシナリオで機能しない場合は、$indexスプライスを使用してインデックス()に基づいてアイテムを削除できます。

私はおそらくそれを次のようにします:http://jsfiddle.net/rniemeyer/N3JaW/

また、eventclickはラッパーのevent)バインディングは、現在のデータを最初の引数としてハンドラーに渡すため、へのバインディングを簡略化できることにも注意してくださいclick: $parent.removeItem

更新:オブジェクトをJSONに変換する方法を制御する方法は次のとおりです。

  • ko.toJSON2番目と3番目の引数をに渡しますJSON.stringify2番目の引数では、ここで説明するように、値を置き換える可能性のある関数を実行できます。valueこれは、キーが数値(配列アイテム)であり、プロパティがあるかどうかを確認するサンプルです。その場合、オブジェクトではなく文字列を返すだけです。 http://jsfiddle.net/rniemeyer/N3JaW/1/

  • オブジェクトにコンストラクター関数を使用する場合は、ここでtoJSON説明するように関数をオーバーライドできます。この機能のサンプルは次のとおりです。http://jsfiddle.net/rniemeyer/N3JaW/2/

  • 使用できる別の手法は、「良好な」値を持つ計算されたオブザーバブルを維持することです。サンプルは次のとおりです:http://jsfiddle.net/rniemeyer/N3JaW/3/。これItemsには、クリーンな値を返す計算されたオブザーバブルがあります。 Items.asObjects値のオブジェクトバージョンが含まれます。JSONに変換すると、JSONに変換するとasObjectsパーツが自然に削除Itemsされます。JSONに変換するときにこの「適切な」配列のみが必要な場合は、他のオプションの方がパフォーマンスが優れています(送信する場合にのみ計算されます)。

于 2012-08-30T16:26:43.773 に答える