TreeNode и работа с узлами

TreeNode является ключевым элементом для построения древовидной структуры компонентов в Carbon Components Svelte. Он представляет собой отдельный узел дерева, который может содержать другие узлы (дочерние элементы), обеспечивая иерархическое представление данных. Каждый узел управляется через свойства и события, позволяя создавать динамические и интерактивные интерфейсы.


Структура TreeNode

Каждый объект TreeNode имеет следующие основные свойства:

  • id – уникальный идентификатор узла, используется для поиска и управления узлом в дереве.
  • label – текстовая метка узла, отображаемая в интерфейсе.
  • children – массив дочерних узлов типа TreeNode, может быть пустым.
  • expanded – логическое значение, указывающее, раскрыт ли узел в данный момент.
  • selected – логическое значение, определяющее, выделен ли узел.
  • disabled – если true, узел становится неактивным и недоступным для взаимодействия.

Пример создания простого узла:

import { TreeNode } from 'carbon-components-svelte';

let node = {
  id: 'node-1',
  label: 'Корневой узел',
  expanded: true,
  selected: false,
  children: [
    {
      id: 'node-1-1',
      label: 'Дочерний узел 1',
      expanded: false,
      selected: false,
      children: []
    }
  ]
};

Вложенные узлы и рекурсия

Для работы с вложенными узлами используется рекурсивное отображение. TreeNode автоматически рендерит дочерние элементы, если массив children не пуст. Это позволяет строить сложные иерархические структуры с произвольной глубиной.

Рекурсивное использование может выглядеть так:



{#each nodes as node (node.id)}
  
    {#if node.children.length > 0}
      
        
      
    {/if}
  
{/each}

Ключевой момент — передача дочерних узлов через слот children, чтобы сохранить структуру дерева.


Управление состоянием узлов

Раскрытие узла управляется через свойство expanded. Оно может изменяться программно или через взаимодействие пользователя. Например, для раскрытия всех узлов:

function expandAll(nodes) {
  nodes.forEach(node => {
    node.expanded = true;
    if (node.children.length > 0) expandAll(node.children);
  });
}

Выбор узла определяется свойством selected. Можно реализовать выделение одного или нескольких узлов. Пример выделения узла по id:

function selectNodeById(nodes, id) {
  nodes.forEach(node => {
    node.selected = node.id === id;
    if (node.children.length > 0) selectNodeById(node.children, id);
  });
}

Обработка событий

TreeNode поддерживает следующие события:

  • on:click – срабатывает при клике на узел.
  • on:expand – при раскрытии узла.
  • on:collapse – при сворачивании узла.
  • on:select – при выборе узла.

Пример использования события выбора:

 handleSelect(e.detail)} />

События передают объект узла через detail, что позволяет легко управлять состоянием дерева.


Динамическое добавление и удаление узлов

Узлы можно добавлять или удалять в любое время. Для этого достаточно модифицировать массив children родительского узла и обновить состояние Svelte.

Пример добавления дочернего узла:

function addChild(parentNode, childNode) {
  parentNode.children.push(childNode);
}

Пример удаления узла по id:

function removeNodeById(nodes, id) {
  return nodes.filter(node => {
    node.children = removeNodeById(node.children, id);
    return node.id !== id;
  });
}

Визуальные особенности

  • Индикатор раскрытия – стрелка, которая указывает на наличие дочерних элементов и меняет направление при expanded.
  • Выделение – визуальное подсвечивание выбранного узла.
  • Отключенные узлы – серый текст и недоступные для клика.

Carbon Components Svelte обеспечивает единый стиль, соответствующий дизайну IBM Carbon, с плавной анимацией раскрытия и высокой отзывчивостью интерфейса.


Практические советы

  • Для больших деревьев рекомендуется использовать ленивую загрузку дочерних узлов: загружать их только при раскрытии родителя, чтобы сократить первоначальную загрузку.
  • Сохранять состояние раскрытия и выделения узлов удобно через двухстороннее связывание Svelte.
  • Для сложных операций лучше использовать рекурсивные функции вместо циклов, чтобы сохранить чистоту кода и поддержку глубины дерева.