Реализация сложной структуры TreeList - PullRequest
1 голос
/ 25 сентября 2019

Мне нужно будет использовать правильный компонент для реализации этого https://imgur.com/a/P2VHX2i.В настоящее время я смотрю на примеры TreeList (https://demos.telerik.com/kendo-ui/treelist/remote-data-binding) с использованием данных JSON с сервера.Можете ли вы дать совет по созданию этого списка?

1 Ответ

1 голос
/ 25 сентября 2019

Я делал PoC один раз для подобного сценария, как ваш.Я имитировал TreeList с помощью Grid, и он работал:

<!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>

Демонстрация в Додзе

Почему я это сделал?Для работы с огромными наборами данных, которые я не знаю, если это ваш случай.Как видите, вышеприведенный TreeList отображает 50 тыс. Строк, виртуализированных.Проблема в том, что TreeList не виртуализируется ( проверить свои документы ), но Grid делает .

Как это работает:

  1. Заблокируйте первый столбец, чтобы он был столбцом коллапса / раскрытия.Вы также можете заблокировать больше столбцов;

  2. В ваших dataItems (данных строки) вы должны использовать некоторые свойства элемента управления: Collapsed, Level, Show иIndex.Они управляют поведением коллапса / расширения и иерархическим отображением.Добавьте console.log(data) перед инициализацией сетки, чтобы проверить, как она была заполнена;

  3. Свойство Show обрабатывает состояние отображения коллапса / раскрытия.Если строка равна Show = false, она будет скрыта.Это работает из-за фильтра в источнике данных: filter: { field: "Show", operator: "eq", value: true };

  4. Событие click в классе item-cell управляет состоянием отображения дочерних элементов строки.Этот класс добавляется в первый столбец как: attributes: { "class": "item-cell" }.Событие изменяет свойство Show для дочерних строк;

  5. В шаблоне line-template будет отображаться правильный уровень выравнивания и стрелки для столбца collpase / expand;

...