1

私は最近、RP Niemeyer による優れたスタック オーバーフローの回答であるKnockoutJS ObservableArray data groupingを使用して、observableArray 内のデータをフィールドごとにグループ化できるようにしました。それは見事に機能しています。問題は、 Knockout Sortableでうまく動作しないことです。sourceParent の取得に問題があります。次のフィドルを参照してください: http://jsfiddle.net/mrfunnel/g6rbc

基本的に、タスクがルート (スケジュールされていない) にグループ化されたネストされたリストと、タスクだけの別のリスト (スケジュールされている) があります。ルートとタスクをスケジュールにドラッグできるようにしたいと考えています。ルートがドラッグされた場合、タスクに分割する必要があります。

どんな援助でも大歓迎です。

4

1 に答える 1

6

バインドは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/。ルート間の並べ替えを許可するかどうかはわかりませんが、サンプルでは無効にしています。個々のタスクまたはルート全体をスケジュールされたタスクにドロップできます。

于 2012-10-10T16:21:05.120 に答える