【问题标题】:Angular create a recursive loop in template to render comments treeAngular 在模板中创建递归循环以呈现评论树
【发布时间】:2018-03-01 21:21:29
【问题描述】:

您好,我想将我的应用程序的 cmets 呈现为 cmets 及其回复,但我不知道如何处理我的数据:

我的数据如下:

"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",
  }
]

其中parent指的是回复评论的id,所以应该显示为:

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

但到目前为止,我只有一个按数据顺序排列的列表

【问题讨论】:

  • 这是您创建的数组还是某种 api 响应?如果您创建了这个,您可能希望有一种更好的方式来组织元素,以便它们可以具有一定的顺序,有助于填充到您的模板中。

标签: angular ngfor


【解决方案1】:

1 您需要整理数据。您需要遍历列表的主要思想找到父母将孩子附加到他们身上,就像这样

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

然后查看这个答案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;
}

他们正在使用树节点组件来创建树。

【讨论】:

    【解决方案2】:

    是的,@alexKhymenko 是对的。您需要将普通树转换为分层树。您可以使用pipes 来执行此操作。然后,您可以渲染一个递归列表来渲染您的分层树。

    管道:

    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;
            });
        }
    }
    

    标记:

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

    请参阅说明这一点的plunk

    【讨论】: