これを処理する良い方法は、item、元の親、新しい親を引数として渡すsortableListバインディングにコールバックオプションを追加することだと思います。ここで
は私がKO 2.0のために使用していることをバインディングがコールバックでどのように見えるかです:
//connect items with observableArrays
ko.bindingHandlers.sortableList = {
init: function(element, valueAccessor, allBindingsAccessor, data, context) {
var options = ko.utils.unwrapObservable(valueAccessor());
//attach the appropriate class to our element
if (ko.bindingHandlers.sortableList.autoAddClass) {
ko.utils.toggleDomNodeCssClass(element, ko.bindingHandlers.sortableList.defaultClass, true);
}
$(element).data("sortList", options.list || valueAccessor()); //attach meta-data
$(element).sortable({
update: function(event, ui) {
var item = ui.item.data("sortItem");
if (item) {
//identify parents
var originalParent = ui.item.data("parentList");
var newParent = ui.item.parent().data("sortList");
//figure out its new position
var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
if (position >= 0) {
originalParent.remove(item);
newParent.splice(position, 0, item);
}
ui.item.remove();
if (options.afterDrop) {
options.afterDrop.call(this, item, newParent, originalParent);
}
}
},
connectWith: '.' + ko.bindingHandlers.sortableList.defaultClass
});
return ko.bindingHandlers.template.init.apply(this, arguments);
},
update: function(element, valueAccessor, allBindingsAccessor, data, context) {
var options = ko.utils.unwrapObservable(valueAccessor()),
newOptions = {};
//build our options to pass to the template engine
if (options.list) {
newOptions.foreach = options.list;
newOptions.name = options.tmpl;
newOptions.includeDestroyed = options.includeDestroyed;
newOptions.afterAdd = options.afterAdd;
newOptions.beforeRemove = options.beforeRemove;
} else {
newOptions.foreach = valueAccessor();
}
//use an afterRender function to add meta-data
if (options.afterRender) {
//wrap the existing function, if it was passed
newOptions.afterRender = function(element, data) {
ko.bindingHandlers.sortableList.afterRender.call(data, element, data);
options.afterRender.call(data, element, data);
}
} else {
newOptions.afterRender = ko.bindingHandlers.sortableList.afterRender;
}
//call the actual template binding
ko.bindingHandlers.template.update(element, function() { return newOptions; }, allBindingsAccessor, data, context);
},
afterRender: function(elements, data) {
ko.utils.arrayForEach(elements, function(element) {
if (element.nodeType === 1) {
$(element).data("sortItem", data);
$(element).data("parentList", $(element).parent().data("sortList"));
}
});
},
defaultClass: 'container',
autoAddClass: true
};
あなたは、その後のようなバインディングを指定します:今
<ul data-bind="sortableList: { tmpl: 'myItems', list: myObservableArray, afterDrop: myCallback }"></ul>
、あなたが追加することができますそのアイテムが移動されたことをサーバーに伝える独自のコールバック。 observableArraysは関数(オブジェクト)なので、実際にプロパティを割り当てることができます。ここで私は、各観察可能な配列にid
プロパティを割り当てられたサンプルがあると私は古い親だったものと新しい親だったかを知るに優しい方法があるように、その後、コールバックでアクセス:
http://jsfiddle.net/rniemeyer/QZscP/
を
あなたの例を使用して、Thanx Ryanは私に似たものを実装しました。私のアプリではアイテムが追加または削除される理由は複数ある可能性があるため、いくつかの追加機能が必要でした。 Btw、ノックアウトについてのあなたの記事は本当に素晴らしいです、私はそれらを頻繁に使用する!私は彼らがなければノックアウトを使用すると思うしないでください。 – RogierBessem
@RogierBessem最近私はこれを少しきれいにして、ここでプロジェクトを作成しました:https://github.com/rniemeyer/knockout-sortable。たぶん新しいバージョンがあなたのために働くかもしれないし、フィードバックを自由に共有することができれば確かです。ありがとう! –