KnockoutJS可排序组observableArray by field和conditionally sort

我最近使用了RP Niemeyer, KnockoutJS ObservableArray数据分组的一个很好的堆栈溢出答案,允许我通过字段将数据分组到observableArray中。 这工作非常出色。 问题是它与Knockout Sortable的搭配并不好。 检索sourceParent存在问题。 请参阅以下小提琴: http : //jsfiddle.net/mrfunnel/g6rbc

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

任何帮助将不胜感激。

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/ 。 我不确定您是否允许在路由之间进行排序,但我在示例中禁用了它。 您可以将单个任务或整个路径放入计划任务中。