Knockout.js:来自observableArray的knockout-sortable css update

时间:2014-10-28 09:42:04

标签: jquery css jquery-ui knockout.js jquery-ui-sortable

我在一些网络项目中使用了很棒的knockout.js lib以及jQuery和jQuery-UI。

在我的应用程序的特殊视图中,我列出了一组任务。这些任务应该是可排序的,所以我想到了jQuery-UI的可排序小部件。当我也使用Knockout时,我发现这个非常有用的Ryan Niemeyer的lib叫做knockout-sortable,它结合了jQuery-sortable和Knockout函数。

<ul> - 元素中列出任务是没有问题的,同时也将相应的<li> - 元素移动到完美的工作中。

<div class="container" data-bind="sortable: tasks">
        <div class="item"  data-bind="css: {highlight:marked}">
            <span>
                <p>
                    <span data-bind="text: id"></span>: 
                    <span data-bind="text: name"></span>
                </p>
            </span>

        </div>
    </div>

但是我需要一个特殊的功能:每次在列表中向上或向下移动某个任务时,应该将列表中的predecessors-task的所有ID保存到单独的数组(predecessors-array)。为了更清楚:我需要信息,直到哪个任务/ <li> - 条目被修改,因为我想稍后用位置[0..<highestIndexOfMovedTask>]的任务做一些事情。为此,我将所有前面的任务ID保存在一个单独的数组中。

所以我在Niemeyer淘汰赛的“afterMove”功能中做到了这一点。这很好,并且所有ID都保存到predecessors-array。

ko.bindingHandlers.sortable.afterMove = function(obj){
    var targetIdx = obj.targetIndex+1;
    if(targetIdx>viewModel.highestTargetId()){
       viewModel.highestTargetId(targetIdx);
    }
    var allItemsUntilTarget = viewModel.tasks().slice(0, viewModel.highestTargetId());
    var itemIdsUntilTarget = $.map(allItemsUntilTarget, function(elem, idx){return elem.id()});
    var oldProducts = viewModel.includeIds.removeAll();
    ko.utils.arrayPushAll(viewModel.includeIds, itemIdsUntilTarget);  
};

下一步使其变得复杂:当然,应该有一个可视化表示所有任务的ID在predecessors-array中。为此,在每个任务上都有一个名为“marked”的计算可观察属性,检查自己的ID是否在predecessors-array中。每次在列表中移动某个任务时,如果任务位于predecessors-array中,则标记属性将新计算为true / false。

这也可以正常工作但如果我将CSS类绑定到marked-property以直观地指示此任务在predecessors-array中,则不会更新CSS。我昨天尝试了5h做了很多研究,但我没有提出解决方案。在模型正确更新的情况下(可以通过chrome的开发者控制台进行检查),视图不是。

也许有人可以帮我解决这个问题?!我在这里发布了一些测试代码:http://jsfiddle.net/njLrxhd5/3

真的欢迎任何帮助!谢谢..


编辑:感谢您的第一个答案。初看:

enter image description here

53:Fix car移至456:fix fence后面的第4位后,我的预期结果应为:

Expected result

因此,如果任务列表中的位置低于移动到数组中最高位置的任务的位置,则所有任务都应将其标记属性设置为true

MVVM的视图模型已经正确响应,但View未更新。

1 个答案:

答案 0 :(得分:0)

搬家前

before move

移动465后:Walk狗UI就像这样 after move

根据您的评论更新了输出:

possible output

小提琴:http://jsfiddle.net/njLrxhd5/26/

在你搬家后

  /*Reset the array so that UI sortable is refreshed */ 
    var array= ko.toJS(viewModel.tasks);

    viewModel.tasks.removeAll();
    viewModel.tasks(array);

基本上它重新填充任务数组,以便刷新可排序的UI。

请注意: 可能有一些有效的方法来进行这种更新(例如父订阅子节点或者可能有一些选项可以在knockout中进行排序)。我只是测试更新功能