Knockout sortable制作重复项(制作树形结构)

时间:2016-06-13 09:59:09

标签: knockout.js knockout-sortable

我正在使用Knockout排序可编辑的树结构,并找到了这个很好的例子:http://jsfiddle.net/rniemeyer/Lqttf

工作正常,但我有一个根节点列表,所以我将根节点绑定更改为树类项目的可排序列表。小提琴:http://jsfiddle.net/yyqnhngm

新模板标记如下所示(请注意,根ul是sortable绑定,而不是原始的template

<script id="nodeTmpl" type="text/html">
    <li>
        <a href="#" data-bind="text: name"></a>
        <div>
           <ul data-bind="sortable: { template: 'nodeTmpl', data: $data.children }"></ul>            
        </div>
    </li>
</script>

<ul data-bind="sortable: { template: 'nodeTmpl', data: root }"></ul>

如果您将B拖到A中,那么B将被复制而不是移动到A.这就是我正在寻找原因和解决方案的问题。我的直接想法是,sortable认为该项目同时被拖入两个列表,可能是因为标记/ html问题,但我无法看到如何。

注意:我知道我可以将所有项目包装成根音符,但这对我的目的来说没有多大意义。

1 个答案:

答案 0 :(得分:1)

在我看来,不支持“普通”数组。将viewmodel中的数组更改为observableArray可为您提供所需的行为。即:

ko.applyBindings({
  root: ko.observableArray([
    new TreeItem("A", []),
    new TreeItem("B", [])
  ])
});

供参考:

根据knockout-sortable readme (强调我的)

  

knockout-sortable是Knockout.js的绑定,旨在将 observableArrays 与jQuery UI的可排序功能连接起来。

我还尝试通过源代码来解释究竟出了什么问题,但找不到确切的原因。我找到了一个片段,似乎至少解释了作者的想法。

代码显示插件的默认行为使用splice方法在数组之间移动元素。这可以解释为什么您的示例未触发异常:Array.prototypeko.observableArray都有splice方法;两者都采取类似的论点。

代码块中的最后一条评论说明targetParentsourceParent应该是可观察的。

if (!sortable.hasOwnProperty("strategyMove") || sortable.strategyMove === false) {
  //do the actual move
  if (targetIndex >= 0) {
    if (sourceParent) {
      sourceParent.splice(sourceIndex, 1);

      //if using deferred updates plugin, force updates
      if (ko.processAllDeferredBindingUpdates) {
        ko.processAllDeferredBindingUpdates();
      }
    }

    targetParent.splice(targetIndex, 0, item);
  }

  //rendering is handled by manipulating the observableArray; ignore dropped element
  dataSet(el, ITEMKEY, null);
}

来源:https://github.com/rniemeyer/knockout-sortable/blob/master/src/knockout-sortable.js#L250