2012-04-21 14 views
20

私はobservableArrayの1つ左のアイテムを移動するボタンを持っています。私は次のようにしています。ただし、categories()[index]が配列から削除され、そのノードのDOM操作(私の場合はjQueryの検証による)が破棄されるという欠点があります。observableArrayで2つのアイテムを交換するにはどうすればよいですか?

DOMノードを保存するために一時変数を使用せずに2つのアイテムをスワップする方法はありますか?

moveUp: function (category) { 
     var categories = viewModel.categories; 
     var length = categories().length; 
     var index = categories.indexOf(category); 
     var insertIndex = (index + length - 1) % length; 

     categories.splice(index, 1); 
     categories.splice(insertIndex, 0, category); 
     $categories.trigger("create"); 
    } 

答えて

36

ここに1つのステップでスワップを行うmoveUpの私のバージョンです:

moveUp: function(category) { 
    var i = categories.indexOf(category); 
    if (i >= 1) { 
     var array = categories(); 
     categories.splice(i-1, 2, array[i], array[i-1]); 
    } 
} 

それでも問題が解決しませんただし、Knockoutはスワップを削除してアクションとして追加することができます。しかし、動くアイテムをサポートするためのノックアウト用のopen issueがあります。 更新:バージョン2.2.0では、Knockoutは移動したアイテムを認識し、foreachバインディングはそれらを再レンダリングしません。 MOVEUP

の彼のバージョンmoveDown

moveDown: function(category) { 
    var array = categories(); 
    var i = categories.indexOf(category); 
    if (i < arr.length) { 
     categories.splice(i, 2, array[i + 1], array[i]); 
    } 
} 
+0

ありがとう、ここでは** moveDown **の例http:// stackoverflowです。com/a/22348385/287084 – Orhaan

0

私はjQueryの私の項目に&ドロップをドラッグしたかったように私は同様の問題がありました。 私の解決策は、knockoutjsテンプレートを使用してbeforeRemoveイベントとafterAddイベントをモデルにバインドすることになりました。 Personクラス/関数は単純なノックアウトビューモデルです。

以下の例では、.draggable()を使用していますが、検証を簡単に使用できます。 observableArrayを操作するための独自のコードを追加してください。

HTML:

<div data-bind="template: {foreach:attendeesToShow, beforeRemove:hideAttendee, afterAdd:showAttendee}"> 
    <div class="person"> 
     <img src="person.jpg" alt="" /> 
     <div data-bind="text: firstName" ></div> 
     <div class="deleteimg" data-bind="click:$parent.removeAttendee" title="Remove"></div> 
    </div> 
</div> 

のViewModel:

+0

できますか?私がしようとしているのは、ユーザーがソートできるようにボタンを使うことです(後でドラッグアンドドロップを実装するかもしれません)。 beforeRemove、afterAddはDOM要素を保持する前にどのように処理するのですか? DOM要素はKnockoutによって生成されましたが、jQueryの検証によって変更されました。アイテムを再挿入してから削除して変更を失います。 –

+0

私の例では、アイテムがDOMに再追加されたときに、ケース検証でdraggableを単に追加し直します。私の場合は、状態変数を保持する必要はありません(それらはすべてモデル内にあります)ので、私のために働きます。検証も同じでなければならない? – jornare

0

おかげで、私はこの答えは少し遅れて来るけど、私はそれがより一般たい他の人に役に立つかもしれないと思いましたスワップソリューション。あなたはそのようなあなたのobservableArraysにスワップ機能を追加することができます。

ko.observableArray.fn.swap = function(index1, index2) { 
    this.valueWillMutate(); 

    var temp = this()[index1]; 
    this()[index1] = this()[index2]; 
    this()[index2] = temp; 

    this.valueHasMutated(); 
} 

あなたは、その後、それぞれのインデックス指定した配列内の2つの要素を交換するために、この機能を使用することができます。

myArray.swap(index1, index2); 

moveUpという機能について、あなたは可能性があり次にこのようなことをしてください:

moveUp: function(category) { 
    var i = categories.indexOf(category); 
    if (i > 0) { 
     categories.swap(i, i+1); 
    } 
} 
+0

バージョンが正しく動作しません。 "arr.length"を "array.length - 1"に置き換えることは、そのトリックを行います。 –