Как встроить древовидную структуру в столбец таблицы

1

Я хочу создать пользовательский интерфейс, который отображает элементы в списке, с дополнительными сведениями, отображаемыми в других столбцах в списке. Когда элемент содержит дочерние элементы, я могу развернуть элемент, а дополнительные строки будут вставлены в таблицу, а имена элементов будут отступы, но остальные столбцы отображаются нормально.

Проблема состоит в том, что обычно древовидная структура выполняется рекурсивно. Но вы не можете, чтобы узел служил родителем дочерних строк, или он разбивает таблицу.

Я смог получить доказательство концепции, например:

<table>
  <thead>
    <th>Item Name</th>
    <th>Summary</th>
    <th>Priority</th>
  </thead>
  <ng-template ngFor let-root [ngForOf]="['a','b','c']">
    <tr>
      <td style="padding-left: 0;">{{root}}</td>
      <td>Summary for {{root}}</td>
      <td>None</td>
    </tr>
    <ng-template ngFor let-child [ngForOf]="['1','2','3']">
      <tr>
        <td style="padding-left: 1em;">{{child}}</td>
        <td>Summary for {{child}}</td>
        <td>None</td>
      </tr>
    </ng-template>
  </ng-template>
</table>

Это работает, потому что <ng-template> не отображается как узел в DOM.

Затем я попытался создать компонент для представления этой концепции:

<tr>
  <td style="padding-left: calc({{depth}}*1em);">
    {{item.nodeName()}}
  </td>
  <td *ngIf="details">{{item.summary}}</td>
  <td *ngIf="details">{{item.priority_name}}</td>
</tr>
<tr *ngIf="loading">
  <td *ngIf="details" style="padding-left: calc({{depth+1}}*1em);" colspan=3>Loading...</td>
  <td *ngIf="! details" style="padding-left: calc({{depth+1}}*1em);">Loading...</td>
</tr>
<ng-template ngFor let-child [ngForOf]="item.children">
  <item-node [item]="child" depth="depth+1" [details]="details"></item-node>    
</ng-template>

К сожалению, это не работает, потому что <item-node> создает узел в DOM, который разбивает таблицу.

Есть ли способ сделать это таким образом, чтобы не вставлять посторонние узлы в DOM?

Теги:
angular

1 ответ

0

Решение состоит в использовании <ng-template> и <ng-container>, чтобы создать рекурсивный шаблон, например:

<ng-template #node>
  <tr><!-- current node --></tr>
  <ng-container *ngIf="expanded">
    <ng-container ngFor let-child [ngForOf]="children">
      <ng-container *ngTemplateOutlet="node; context:child"></ng-container>
    </ng-container>
  </ng-container>
</ng-template>
<table>
  <thead><!-- column headers --></thead>
  <ng-container *ngTemplateOutlet="node; context: root"></ng-container>
</table>

Есть более подробная информация, которая должна быть разработана, например, как сделать отступ работы (вам нужно следить за глубиной и добавлять стиль, отступы на основе глубины), вам нужно передать переменные, которые нужно вытащить из контекста и т.д. Но проблема с корнем, как избежать ненужных элементов в DOM, решается с помощью <ng-container> а дочерние узлы обрабатываются с помощью рекурсивного <ng-template> вместо stand- один компонент.

Подробнее читайте в <ng-template> и <ng-container>.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню