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

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

Структура данных


const comments:Comment[] = [
  {
    text: "1",
    comments: [
      {
        text: "1.1",
        comments: [
          {
            text: "1.1.1 "
          }
        ]
      },
      {
        text: "1.2",
        comments: [
          {
            text: "1.2.1"
          }
        ]
      }
    ]
  },
  {
    text: "2",
    comments: [
      {
        text: "2.1",
        comments: [
          {
            text: "2.1.1"
          }
        ]
      }
    ]
  }
];

Это данные, которые мы ожидаем получить от сервера. Для текущего примера сделаем их статичными.

Comments component


@Component({
  selector: 'comments',
  template: `
     <div *ngFor="let comment of comments">
      <ul>
       <li>
         {{comment.text}}
         <comments [comments]="comment.comments" 
             *ngIf="comment.comments"></comments>
       </li>
      </ul>
    </div>
  `,
})
export class CommentComponent {
  @Input() comments;
}

Как вы видите, мы вызываем компонент рекурсивно. В случае когда нет вложенных комментариев, чтобы не отображать компонент используется директива ngif.

App Component


@Component({
  selector: 'my-app',
  template: `
   <comments [comments]="postComments"></comments>
  `,
})
export class App {
  postComments = postComments;
}

Результат



Ссылки


пример на stackblitz
angular ru telegram

Комментарии (9)


  1. artsavel
    21.03.2018 23:11

    Так и хочется спросить: «Простите, и?»


    1. bluetooth
      22.03.2018 11:08
      +2

      Попытка написать самую короткую статью на Хабре?


      1. klimentRu Автор
        22.03.2018 17:50

        1. Это перевод
        2. Инфа полезная поэтому решил выложить


    1. bores
      22.03.2018 14:36

      Статью надо читать рекурсивно


  1. bluetooth
    22.03.2018 11:15

    Именно для этих входных данных легче исползовать тэг

    <ol>


  1. Adizka
    22.03.2018 12:11

    Увы, но в --aot выкинет warning о возможной бесконечной зацикленности.
    Решение только через ng-template/ng-container


    1. klimentRu Автор
      22.03.2018 12:16

      Возможно у Вас не корректный ngIf
      В статье есть пример warning не выдает.
      Angular CLI: 1.6.7
      Node: 8.4.0
      OS: win32 x64
      Angular: 5.2.8