KnockoutJS可排序组observableArray by field和conditionally sort [英] KnockoutJS Sortable group observableArray by field and conditionally sort

查看:173
本文介绍了KnockoutJS可排序组observableArray by field和conditionally sort的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have recently used a great stack overflow answer by RP Niemeyer, KnockoutJS ObservableArray data grouping, to allow me to group data in an observableArray by a field. That is working brilliantly. The problem is it is not playing nicely with Knockout Sortable. There is a problem with retrieving the sourceParent. Please see the following fiddle: http://jsfiddle.net/mrfunnel/g6rbc

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

Basically I have one nested list where tasks are grouped into routes (unscheduled) and another list of just tasks (scheduled). I want to be able to drag routes and tasks into scheduled. If a route is dragged in it needs to split up into tasks.

非常感谢任何帮助。

推荐答案

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

The sortable binding only works against observableArrays, because it needs to know how to write the dropped value back to the array. With the result of a computed observable, it would not be able to write it in a meaningful way.

这是您可以构建代码的另一种方法。基本上,您将构建一个observableArray路由,每个路由都包含一个observableArray任务。类似于:

Here is an alternative way that you might be able to structure your code. Basically, you would build an observableArray of routes that each contain an observableArray of tasks. Something like:

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 回调在您的计划任务上检查它是否是路线而不是单个任务并执行拆分,如:

Then, you can use the beforeMove callback on your scheduled tasks to check if it is a route rather than an individual task and do the splitting like:

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

Here is an updated sample: http://jsfiddle.net/rniemeyer/BeZ2c/. I am not sure if you allow sorting between the routes, but I disabled that in the sample. You can drop individual tasks or entire routes into the scheduled tasks.

这篇关于KnockoutJS可排序组observableArray by field和conditionally sort的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆