1

我最近使用了 RP Niemeyer 提供的一个很好的堆栈溢出答案,KnockoutJS ObservableArray data grouping,允许我按字段对 observableArray 中的数据进行分组。那工作得很好。问题是它不能很好地与Knockout Sortable一起使用。检索 sourceParent 时出现问题。请看下面的小提琴:http: //jsfiddle.net/mrfunnel/g6rbc

基本上我有一个嵌套列表,其中任务被分组到路由(未计划)和另一个任务列表(计划)中。我希望能够将路线和任务拖入计划中。如果将路线拖入,则需要将其拆分为任务。

任何帮助将不胜感激。

4

1 回答 1

6

sortable绑定仅适用于 observableArrays,因为它需要知道如何将删除的值写回数组。对于计算出的 observable 的结果,它将无法以有意义的方式编写它。

这是您可以构建代码的另一种方法。基本上,您将构建一个 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 回答