3

Hi I want to render the comments of my applications as comments and its reply's but I dont have idea on how to do it with my data:

My data looks like:

"comments": [
  {
    "id": "30",
    "content": "Comment 1",
    "parent": "0",
  },
  {
    "id": "31",
    "content": "Comment 2",
    "parent": "0",
  },
  {
    "id": "32",
    "content": "comment 3",
    "parent": "0",
  },
  {
    "id": "33",
    "content": "sub comment 1-1",
    "parent": "30",
  },
  {
    "id": "34",
    "content": "sub comment 2-1",
    "parent": "31",
  },
  {
    "id": "35",
    "content": "sub sub comment 1-1-1",
    "parent": "33",
  },
  {
    "id": "36",
    "content": "sub comment 1-2",
    "parent": "30",
  }
]

where parent refers to the id of the comment that reply, so it shoold be shown like:

Comment 1
  sub comment 1-1
    sub sub comment 1-1-1
  sub comment 1-2
Comment 2
  sub comment 2-1
Comment 3

but until now i only have a list in the order of my data

efirvida
  • 4,592
  • 3
  • 42
  • 68
  • is this an array you created or some kind of an api response? If you created this, you probably want to have a better way of organizing the elements so that they can be of certain order that helps in populating in your template. – amal Sep 20 '17 at 17:46

2 Answers2

3

Yes, @alexKhymenko is right. You need to convert your plain tree to a hierarchical tree. You can use pipes to do this. Then, you can render a recursive list to render your hierarchical tree.

Pipe:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'converter' })
export class ConverterPipe implements PipeTransform {
    transform(array: any[], id: string = "id", parentId: string = "parent", rootValue: any = "0"): any[] {
        return this.filterNodes(array, id, parentId, rootValue);
    }
    filterNodes(array: any[], id: string, parentId: string, parentValue: any): any[] {
        return array.filter((node) => {
            return node[parentId] === parentValue;
        }).map((node) => {
            node["items"] = this.filterNodes(array, id, parentId, node[id]);
            return node;
        });
    }
}

Markup:

<ng-template #List let-items>
    <ul>
        <li *ngFor="let item of items">
            {{item.content}}
            <ng-container *ngTemplateOutlet="List; context:{ $implicit: item.items }"></ng-container>
        </li>
    </ul>
</ng-template>
<ng-container *ngTemplateOutlet="List; context:{ $implicit: comments | converter }"></ng-container>

See the plunk that illustrates this.

Gosha_Fighten
  • 3,838
  • 1
  • 20
  • 31
2

1 You need to arganize your data. Main idea you need to iterate over list find parents append childrens to them something like this

node = {name: 'root', children: [
{name: 'a', children: []},
{name: 'b', children: []},
{name: 'c', children: [
  {name: 'd', children: []},
  {name: 'e', children: []},
  {name: 'f', children: []},
  ]},
 ]};  

Then Checkout this answer Use component in itself recursively to create a tree

 @Component({
 selector: 'tree-node',
 template: `
 <div>{{node.name}}</div>
 <ul>
   <li *ngFor="let node of node.children">
     <tree-node  [node]="node"></tree-node>
   </li>
 </ul>
 `
})
export class TreeNode {
  @Input() node;
}

They are using tree node component to create tree.

alexKhymenko
  • 5,450
  • 23
  • 40