实现复杂的 TreeList 结构
Implementing complex TreeList structure
我需要使用正确的组件来实现这个 https://imgur.com/a/P2VHX2i . I'm currently looking at TreeList Examples ( https://demos.telerik.com/kendo-ui/treelist/remote-data-binding ) 使用来自服务器的 json 数据。你能就创建这个树列表提出一些建议吗?
我曾针对与您类似的场景做过一次 PoC。我已经用网格模拟了一个 TreeList,它起作用了:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.mobile.all.min.css">
<style type="text/css">
.item-level {
display: inline-block;
width: 10px;
}
.level-arrow-expanded:before {
content: "[=10=]bb"
}
.level-arrow-collapsed:before {
content: "[=10=]ab"
}
.item-cell {
cursor: pointer
}
td[role="gridcell"] {
padding: 0;
}
.cell-container {
display: inline-block;
padding-bottom: 6.4px;
padding-left: 9.6px;
padding-right: 9.6px;
padding-top: 6.4px;
box-sizing: border-box;
width: 100%;
}
.header-container {
padding: 0
}
.header-editable-cell {
color: #9cc3e5;
font-weight: bold
}
.k-grid tr:hover td .cell-container {
background-color: #bdb4af !important
}
</style>
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/kendo.all.min.js"></script>
<script id="line-template" type="text/x-kendo-template">
<div class='cell-container'>
<div class='item-level #= (data.Level < 4 ? "level-arrow-" + (data.Collapsed ? "collapsed" : "expanded") : "") #'></div>
# for (let i = -1; i < (data.Level - 1); i++) { #
<div class='item-level level-space'></div>
# } #
#= data.Line #
</div>
</script>
<script>
$(function() {
const lineTemplate = $("#line-template").html();
let data = [];
let cols = [{
title: " ",
field: "Line",
locked: true,
width: 200,
template: lineTemplate,
attributes: { "class": "item-cell" }
}, {
title: "Customer Type",
field: "CustomerType",
width: 300
}];
for (var n = 0; n < 50000; n++) {
let level = (n % 5),
dataItem = {
Line: n,
CustomerType: (n % 2 == 0 ? "All" : "3rd Party"),
Level: level,
Show: true,
Index: n,
Collapsed: false
};
data.push(dataItem);
}
let grid = $("#grid").kendoGrid({
dataSource: {
data: data,
pageSize: 20,
filter: { field: "Show", operator: "eq", value: true }
},
height: 500,
columns: cols,
scrollable: {
virtual: true
}
}).data("kendoGrid");
grid.lockedTable.on("click", "td.item-cell", function() {
let data = grid.dataSource.data(),
dataItem = grid.dataItem($(this).closest("tr")),
item;
for (let i = 0, count = data.length; i < count; i++) {
item = data[i];
if (item.Index == dataItem.Index) {
dataItem.Collapsed = !dataItem.Collapsed;
}
else if (item.Index > dataItem.Index) {
if (dataItem.Index != i && item.Level == 0) {
break;
}
item.Show = !dataItem.Collapsed;
}
}
grid.dataSource.fetch();
});
});
</script>
</head>
<body>
<div id="grid"></div>
</body>
</html>
我为什么这么做?要处理巨大的数据集,我不知道你的情况是否如此。如您所见,上面的 TreeList 显示了 50k 行,已虚拟化。问题是 TreeList 没有虚拟化(check out it's docs), but Grid does.
工作原理:
将第一列锁定为 collpase/expand 列。您还可以锁定更多列;
在你的数据项(行的数据)中,你必须使用一些控件属性,它们是:Collapsed
、Level
、Show
和 Index
.它们控制 collpase/expand 行为和分层显示。在 Grid 的初始化之前添加一个 console.log(data)
以检查它是如何填充的;
Show
属性处理collpase/expand显示状态。一旦一行为 Show = false
,它将被隐藏。这是因为数据源中的过滤器:filter: { field: "Show", operator: "eq", value: true }
;
item-cell
class 上的单击事件管理行的子项显示状态。 class 在第一列中添加为:attributes: { "class": "item-cell" }
。该事件更改了子行的 Show
属性;
模板 line-template
将显示 collpase/expand 列的正确级别指示和箭头;
我需要使用正确的组件来实现这个 https://imgur.com/a/P2VHX2i . I'm currently looking at TreeList Examples ( https://demos.telerik.com/kendo-ui/treelist/remote-data-binding ) 使用来自服务器的 json 数据。你能就创建这个树列表提出一些建议吗?
我曾针对与您类似的场景做过一次 PoC。我已经用网格模拟了一个 TreeList,它起作用了:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.917/styles/kendo.mobile.all.min.css">
<style type="text/css">
.item-level {
display: inline-block;
width: 10px;
}
.level-arrow-expanded:before {
content: "[=10=]bb"
}
.level-arrow-collapsed:before {
content: "[=10=]ab"
}
.item-cell {
cursor: pointer
}
td[role="gridcell"] {
padding: 0;
}
.cell-container {
display: inline-block;
padding-bottom: 6.4px;
padding-left: 9.6px;
padding-right: 9.6px;
padding-top: 6.4px;
box-sizing: border-box;
width: 100%;
}
.header-container {
padding: 0
}
.header-editable-cell {
color: #9cc3e5;
font-weight: bold
}
.k-grid tr:hover td .cell-container {
background-color: #bdb4af !important
}
</style>
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.917/js/kendo.all.min.js"></script>
<script id="line-template" type="text/x-kendo-template">
<div class='cell-container'>
<div class='item-level #= (data.Level < 4 ? "level-arrow-" + (data.Collapsed ? "collapsed" : "expanded") : "") #'></div>
# for (let i = -1; i < (data.Level - 1); i++) { #
<div class='item-level level-space'></div>
# } #
#= data.Line #
</div>
</script>
<script>
$(function() {
const lineTemplate = $("#line-template").html();
let data = [];
let cols = [{
title: " ",
field: "Line",
locked: true,
width: 200,
template: lineTemplate,
attributes: { "class": "item-cell" }
}, {
title: "Customer Type",
field: "CustomerType",
width: 300
}];
for (var n = 0; n < 50000; n++) {
let level = (n % 5),
dataItem = {
Line: n,
CustomerType: (n % 2 == 0 ? "All" : "3rd Party"),
Level: level,
Show: true,
Index: n,
Collapsed: false
};
data.push(dataItem);
}
let grid = $("#grid").kendoGrid({
dataSource: {
data: data,
pageSize: 20,
filter: { field: "Show", operator: "eq", value: true }
},
height: 500,
columns: cols,
scrollable: {
virtual: true
}
}).data("kendoGrid");
grid.lockedTable.on("click", "td.item-cell", function() {
let data = grid.dataSource.data(),
dataItem = grid.dataItem($(this).closest("tr")),
item;
for (let i = 0, count = data.length; i < count; i++) {
item = data[i];
if (item.Index == dataItem.Index) {
dataItem.Collapsed = !dataItem.Collapsed;
}
else if (item.Index > dataItem.Index) {
if (dataItem.Index != i && item.Level == 0) {
break;
}
item.Show = !dataItem.Collapsed;
}
}
grid.dataSource.fetch();
});
});
</script>
</head>
<body>
<div id="grid"></div>
</body>
</html>
我为什么这么做?要处理巨大的数据集,我不知道你的情况是否如此。如您所见,上面的 TreeList 显示了 50k 行,已虚拟化。问题是 TreeList 没有虚拟化(check out it's docs), but Grid does.
工作原理:
将第一列锁定为 collpase/expand 列。您还可以锁定更多列;
在你的数据项(行的数据)中,你必须使用一些控件属性,它们是:
Collapsed
、Level
、Show
和Index
.它们控制 collpase/expand 行为和分层显示。在 Grid 的初始化之前添加一个console.log(data)
以检查它是如何填充的;Show
属性处理collpase/expand显示状态。一旦一行为Show = false
,它将被隐藏。这是因为数据源中的过滤器:filter: { field: "Show", operator: "eq", value: true }
;item-cell
class 上的单击事件管理行的子项显示状态。 class 在第一列中添加为:attributes: { "class": "item-cell" }
。该事件更改了子行的Show
属性;模板
line-template
将显示 collpase/expand 列的正确级别指示和箭头;