Knockout sortable makes duplicates(制作树状结构)
Knockout sortable makes duplicates (making a tree structure)
我正在使用 Knockout sortable 制作一个可编辑的树结构,并找到了这个很好的例子:http://jsfiddle.net/rniemeyer/Lqttf
这很好用,但我有一个根节点列表,所以我也将根节点绑定更改为可排序的树项列表。 Fiddle: 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 认为该项目同时被拖入两个列表,可能是因为 markup/html 问题,但我看不出如何。
注意:我知道我可以将所有项目包装到一个根注释中,但这对我的目的来说意义不大。
在我看来,不支持 "ordinary" 数组。将视图模型中的数组更改为 observableArray
可为您提供所需的行为。即:
ko.applyBindings({
root: ko.observableArray([
new TreeItem("A", []),
new TreeItem("B", [])
])
});
供参考:
根据 knockout-sortable readme (强调我的):
knockout-sortable is a binding for Knockout.js designed to connect observableArrays with jQuery UI's sortable functionality.
我也试图通过源代码来解释到底出了什么问题,但找不到确切的原因。我确实找到了一个片段,似乎至少解释了作者的想法。
代码显示插件的默认行为使用 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
我正在使用 Knockout sortable 制作一个可编辑的树结构,并找到了这个很好的例子:http://jsfiddle.net/rniemeyer/Lqttf
这很好用,但我有一个根节点列表,所以我也将根节点绑定更改为可排序的树项列表。 Fiddle: 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 认为该项目同时被拖入两个列表,可能是因为 markup/html 问题,但我看不出如何。
注意:我知道我可以将所有项目包装到一个根注释中,但这对我的目的来说意义不大。
在我看来,不支持 "ordinary" 数组。将视图模型中的数组更改为 observableArray
可为您提供所需的行为。即:
ko.applyBindings({
root: ko.observableArray([
new TreeItem("A", []),
new TreeItem("B", [])
])
});
供参考:
根据 knockout-sortable readme (强调我的):
knockout-sortable is a binding for Knockout.js designed to connect observableArrays with jQuery UI's sortable functionality.
我也试图通过源代码来解释到底出了什么问题,但找不到确切的原因。我确实找到了一个片段,似乎至少解释了作者的想法。
代码显示插件的默认行为使用 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