我正在使用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问题,但我无法看到如何。
注意:我知道我可以将所有项目包装成根音符,但这对我的目的来说没有多大意义。
答案 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.prototype
和ko.observableArray
都有splice
方法;两者都采取类似的论点。
代码块中的最后一条评论说明targetParent
和sourceParent
应该是可观察的。
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