【问题标题】:Implementing complex TreeList structure实现复杂的 TreeList 结构
【发布时间】:2019-09-25 10:33:02
【问题描述】:

我需要使用正确的组件来实现这个 https://imgur.com/a/P2VHX2i 。我目前正在使用来自服务器的 json 数据查看 TreeList 示例(https://demos.telerik.com/kendo-ui/treelist/remote-data-binding)。您能否就创建此树列表提供一些建议?

【问题讨论】:

    标签: javascript kendo-ui telerik kendo-treelist


    【解决方案1】:

    我曾经为与您类似的场景做过一次 PoC。我用 Grid 模拟了一个 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: "\00bb"
        }
        .level-arrow-collapsed:before {
          content: "\00ab"
        }
        .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: "&nbsp;",
            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>

    Demo in Dojo

    我为什么这样做?使用我不知道是否是您的情况的庞大数据集。如您所见,上面的 TreeList 显示 50k 行,虚拟化。问题是TreeList没有虚拟化(check out it's docs),而是Grid does

    工作原理:

    1. 将第一列锁定为折叠/展开列。您还可以锁定更多列;

    2. 在你的dataItems(行的数据)中,你必须使用一些控件属性,它们是:CollapsedLevelShowIndex。它们控制折叠/展开行为和分层显示。在 Grid 初始化之前添加 console.log(data) 以检查它是如何填充的;

    3. Show 属性处理折叠/展开显示状态。一旦一行是Show = false,它将被隐藏。这是因为数据源中有一个过滤器:filter: { field: "Show", operator: "eq", value: true };

    4. item-cell 类上的单击事件管理行的子级显示状态。该类在第一列中添加为:attributes: { "class": "item-cell" }。该事件更改子行的Show 属性;

    5. 模板line-template 将显示正确的级别索引和折叠/展开列的箭头;

    【讨论】:

    • 我尝试模拟相同的实现,从服务器获取数据源,但点击事件停止正常工作。你能看看吗? dojo.telerik.com/ugUbAXuT/3
    • @JordanMichael 当您修改数据源时,您忘记保留处理折叠/展开功能的过滤设置。看看:dojo.telerik.com/ugUbAXuT/4
    猜你喜欢
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多