バインドはsortable
、ドロップされた値を配列に書き戻す方法を知る必要があるため、observableArrays に対してのみ機能します。計算されたオブザーバブルの結果では、意味のある方法でそれを書くことができません。
コードを構造化する別の方法を次に示します。基本的に、それぞれがタスクの observableArray を含むルートの observableArray を構築します。何かのようなもの:
self.tasks.subscribe(function(tasks) {
var routes = [],
routeIndex = {};
ko.utils.arrayForEach(tasks || [], function(task) {
var routeId = task.routeId(),
routeTasks = routeIndex[routeId];
//first time that we have seen this routeID
if (!routeTasks) {
//add it to the index, so we can find it without looping next time
routeIndex[routeId] = routeTasks = { id: routeId, tasks: ko.observableArray() };
//add it to the array that we will eventually return
routes.push(routeTasks);
}
routeTasks.tasks.push(task);
});
//return an array of routes that each contain an array of tasks
self.tasksByRoute(routes);
});
次に、スケジュールされたタスクでコールバックを使用して、beforeMove
それが個々のタスクではなくルートであるかどうかを確認し、次のように分割できます。
self.myDropCallback = function(arg) {
var spliceArgs;
//determine if this is really a route rather than an individual task
if (arg.item && arg.item.tasks) {
//we will handle the drop ourselves, since we have to split into tasks
arg.cancelDrop = true;
//build up args, since first two need to be new index and items to remove
spliceArgs = [arg.targetIndex, null];
//add the tasks to the args
spliceArgs.push.apply(spliceArgs, arg.item.tasks());
//splice in the tasks at the right index
arg.targetParent.splice.apply(arg.targetParent, spliceArgs);
//remove the originals, after cancel has happened
setTimeout(function() {
arg.sourceParent.remove(arg.item);
}, 0);
}
};
更新されたサンプルは次のとおりです: http://jsfiddle.net/rniemeyer/BeZ2c/。ルート間の並べ替えを許可するかどうかはわかりませんが、サンプルでは無効にしています。個々のタスクまたはルート全体をスケジュールされたタスクにドロップできます。