敲除嵌套排序 sourceParent.splice 不是函数
Knockout nested sortable sourceParent.splice is not a function
这里我正在处理使用 Knockout sortable 的代码。它应该显示 3 层以上的嵌套排序。
数据传给了模板,但有些元素return被拖放到原来的位置(例如最上层的A,B元素)。
nested sortable应该怎么配置才能让最上层也能正常使用不报错?
错误:
knockout-sortable.js:244 Uncaught TypeError: sourceParent.splice is not a function
or
knockout-sortable.js:252 Uncaught TypeError: targetParent.splice is not a function
JSFiddle - Similar working example
var viewModel = function() {
var self = this;
self.children = ko.observable([{
"name": "A",
"children": [{
"name": "A1",
"children": [{
"name": "A11"
}, {
"name": "A12"
}]
}, {
"name": "A2"
}]
}, {
"name": "B",
"children": [{
"name": "B1"
}, {
"name": "B2"
}]
}]);
}
ko.applyBindings(new viewModel());
ul {
border: solid 1px green;
list-style-type: none;
margin:0px;
}
li {
padding: 10px;
border: solid 1px blue;
margin:0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<script id="nodeTmpl" type="text/html">
<li>
<!-- ko if: $data.name -->
<a href="#" data-bind="text: $data.name"></a>
<!-- /ko -->
<!-- ko if: $data.children -->
<ul data-bind="sortable: { template: 'nodeTmpl', data: $data.children }"></ul>
<!-- /ko -->
</li>
</script>
<ul data-bind="sortable: { template: 'nodeTmpl', data: $root.children }"></ul>
问题已通过更改行 <ul data-bind="template: { name: 'nodeTmpl', data: $root }"></ul>
解决,我从一些参考中删除了 $data
,因为它导致了错误。
var viewModel = function() {
var self = this;
self.children = [{
"name": "A",
"children": [{
"name": "A1",
"children": [{
"name": "A11",
}, {
"name": "A12",
}]
}, {
"name": "A2",
}]
}, {
"name": "B",
"children": [{
"name": "B1",
}, {
"name": "B2",
}]
}]
};
ko.applyBindings(new viewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<script id="nodeTmpl" type="text/html">
<li>
<!-- ko if: $data.name -->
<a href="#" data-bind="text: name"></a>
<!-- /ko -->
<!-- ko if: $data.children -->
<ul data-bind="sortable: { template: 'nodeTmpl', data: children }"></ul>
<!-- /ko -->
</li>
</script>
<ul data-bind="template: { name: 'nodeTmpl', data: $root }"></ul>
Peter Gerhat提供的解决方案不正确。
问题是 observable of an array was used, rather than an observableArray.
错误表明 sourceParent
(从中拖动元素的视图模型上的集合)没有 splice
函数。这是正确的,可观察对象没有 splice
函数,而 array
或 observableArray
有。这同样适用于 targetParent
(这是元素被拖动到的视图模型上的集合)。
要使初始示例正常工作,只需将 observable
更改为 observableArray
。
但是,正如您将在 Peter Gerhat 提供的原始示例和解决方案中注意到的那样,即使没有抛出错误,它仍然无法正常工作。您会注意到,当您拖动元素时,它们要么根本不动,要么消失。
这里的解决方案是将每个 array
变成一个 observableArray
,这样它们就可以通过 sortable
-binding 进行更新。
var viewModel = function() {
var self = this;
self.children = ko.observableArray([{
"name": "A",
"children": ko.observableArray([{
"name": "A1",
"children": ko.observableArray([{
"name": "A11"
}, {
"name": "A12"
}])
}, {
"name": "A2"
}])
}, {
"name": "B",
"children": ko.observableArray([{
"name": "B1"
}, {
"name": "B2"
}])
}]);
}
ko.applyBindings(new viewModel());
ul {
border: solid 1px green;
list-style-type: none;
margin: 0px;
}
li {
padding: 10px;
border: solid 1px blue;
margin: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<script id="nodeTmpl" type="text/html">
<li>
<!-- ko if: $data.name -->
<a href="#" data-bind="text: $data.name"></a>
<!-- /ko -->
<!-- ko if: $data.children -->
<ul data-bind="sortable: { template: 'nodeTmpl', data: $data.children }"></ul>
<!-- /ko -->
</li>
</script>
<ul data-bind="sortable: { template: 'nodeTmpl', data: $root.children }"></ul>
这里我正在处理使用 Knockout sortable 的代码。它应该显示 3 层以上的嵌套排序。
数据传给了模板,但有些元素return被拖放到原来的位置(例如最上层的A,B元素)。
nested sortable应该怎么配置才能让最上层也能正常使用不报错?
错误:
knockout-sortable.js:244 Uncaught TypeError: sourceParent.splice is not a function
or
knockout-sortable.js:252 Uncaught TypeError: targetParent.splice is not a function
JSFiddle - Similar working example
var viewModel = function() {
var self = this;
self.children = ko.observable([{
"name": "A",
"children": [{
"name": "A1",
"children": [{
"name": "A11"
}, {
"name": "A12"
}]
}, {
"name": "A2"
}]
}, {
"name": "B",
"children": [{
"name": "B1"
}, {
"name": "B2"
}]
}]);
}
ko.applyBindings(new viewModel());
ul {
border: solid 1px green;
list-style-type: none;
margin:0px;
}
li {
padding: 10px;
border: solid 1px blue;
margin:0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<script id="nodeTmpl" type="text/html">
<li>
<!-- ko if: $data.name -->
<a href="#" data-bind="text: $data.name"></a>
<!-- /ko -->
<!-- ko if: $data.children -->
<ul data-bind="sortable: { template: 'nodeTmpl', data: $data.children }"></ul>
<!-- /ko -->
</li>
</script>
<ul data-bind="sortable: { template: 'nodeTmpl', data: $root.children }"></ul>
问题已通过更改行 <ul data-bind="template: { name: 'nodeTmpl', data: $root }"></ul>
解决,我从一些参考中删除了 $data
,因为它导致了错误。
var viewModel = function() {
var self = this;
self.children = [{
"name": "A",
"children": [{
"name": "A1",
"children": [{
"name": "A11",
}, {
"name": "A12",
}]
}, {
"name": "A2",
}]
}, {
"name": "B",
"children": [{
"name": "B1",
}, {
"name": "B2",
}]
}]
};
ko.applyBindings(new viewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<script id="nodeTmpl" type="text/html">
<li>
<!-- ko if: $data.name -->
<a href="#" data-bind="text: name"></a>
<!-- /ko -->
<!-- ko if: $data.children -->
<ul data-bind="sortable: { template: 'nodeTmpl', data: children }"></ul>
<!-- /ko -->
</li>
</script>
<ul data-bind="template: { name: 'nodeTmpl', data: $root }"></ul>
Peter Gerhat提供的解决方案不正确。 问题是 observable of an array was used, rather than an observableArray.
错误表明 sourceParent
(从中拖动元素的视图模型上的集合)没有 splice
函数。这是正确的,可观察对象没有 splice
函数,而 array
或 observableArray
有。这同样适用于 targetParent
(这是元素被拖动到的视图模型上的集合)。
要使初始示例正常工作,只需将 observable
更改为 observableArray
。
但是,正如您将在 Peter Gerhat 提供的原始示例和解决方案中注意到的那样,即使没有抛出错误,它仍然无法正常工作。您会注意到,当您拖动元素时,它们要么根本不动,要么消失。
这里的解决方案是将每个 array
变成一个 observableArray
,这样它们就可以通过 sortable
-binding 进行更新。
var viewModel = function() {
var self = this;
self.children = ko.observableArray([{
"name": "A",
"children": ko.observableArray([{
"name": "A1",
"children": ko.observableArray([{
"name": "A11"
}, {
"name": "A12"
}])
}, {
"name": "A2"
}])
}, {
"name": "B",
"children": ko.observableArray([{
"name": "B1"
}, {
"name": "B2"
}])
}]);
}
ko.applyBindings(new viewModel());
ul {
border: solid 1px green;
list-style-type: none;
margin: 0px;
}
li {
padding: 10px;
border: solid 1px blue;
margin: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<script id="nodeTmpl" type="text/html">
<li>
<!-- ko if: $data.name -->
<a href="#" data-bind="text: $data.name"></a>
<!-- /ko -->
<!-- ko if: $data.children -->
<ul data-bind="sortable: { template: 'nodeTmpl', data: $data.children }"></ul>
<!-- /ko -->
</li>
</script>
<ul data-bind="sortable: { template: 'nodeTmpl', data: $root.children }"></ul>