使用角度ngFor从json进行递归列表渲染

时间:2019-04-29 10:12:31

标签: angular typescript

以下数据应在逻辑上转换为列表项。

{
   "text":"root",
   "children":[
      {
         "text":"Unordered Item One",
         "children":[],
         "type":"unordered-list-item"
      },
      {
         "text":"Unordered Item Two",
         "children":[],
         "type":"unordered-list-item"
      },
      {
         "text":"Unordered Item three",
         "children":[
            {
               "text":"Ordered Item A",
               "children":[],
               "type":"ordered-list-item"
            },
            {
               "text":"Ordered Item B",
               "children":[],
               "type":"ordered-list-item"
            }
         ],
         "type":"unordered-list-item"
      }
   ],
   "type":"unordered-list-item"
}

因此最终的输出预期如下所示,

<ul>
    <li>Unordered Item One</li>
    <li>Unordered Item Two</li>
    <li>Unordered Item three</li>
    <li> 
        <ol>
            <li>Ordered Item A</li>
            <li>Ordered Item B</li>
        </ol>
    </li>   
</ul>

我创建了recursion组件来渲染所有这些项目,

在我的应用程序组件中,

<ng-container *ngIf="nested.type==='unordered-list-item'">
    <li>{{nested.text}}</li>
    <ul *ngIf="nested.children.length > 0">
        <app-recursion *ngFor="let child of nested.children" [children]="child.children" [text]="child.text"></app-recursion>
    </ul>
</ng-container> 

在递归组件中,

<ng-container *ngIf="nested.type==='unordered-list-item'">
  <li>{{text}}</li>
</ng-container>

但是它不会呈现子项,请在这里告诉我我做错了什么。

下面是我的项目的工作链接,

https://stackblitz.com/edit/angular-wvztjy?file=src%2Fapp%2Frecursion%2Frecursion.component.html

4 个答案:

答案 0 :(得分:2)

这不起作用,因为递归组件中没有nested这样的输入属性。恕我直言,您不需要每个Child对象都需要的输入属性。

具有类似的内容:

应用程序组件

<ng-container *ngIf="nested.type==='unordered-list-item'">
    <li>{{nested.text}}</li>
    <ul *ngIf="nested.children.length > 0">
        <app-recursion *ngFor="let child of nested.children" [child]="child"></app-recursion>
    </ul>
</ng-container>

递归组件。

<ng-container *ngIf="child?.type==='unordered-list-item'">
  <li>{{child.text}}</li>
  <ng-container *ngIf="child.children?.length > 0">
    <ul>
            <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
    </ul>
  </ng-container>
</ng-container>

<ng-container *ngIf="child?.type==='ordered-list-item'">
  <li>{{child.text}}</li>
  <ng-container *ngIf="child.children?.length > 0">
    <ol>
            <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
    </ol>
  </ng-container>
</ng-container>

在此处查看示例:https://stackblitz.com/edit/angular-qzezhp?file=src%2Fapp%2Frecursion%2Frecursion.component.html

编辑

根据当前逻辑,列表类型由父级决定,例如,如果根中的最后一个子代具有类型:“ ordered-list-item”,并且其子代具有unordred-list-item类型,则仍然有序列表的生成类似于:

<ng-container *ngIf="child?.type==='ordered-list-item'">
  <li>{{child.text}}</li>
  <ng-container *ngIf="child.children?.length > 0">
    <ol>  <-- even though children are un-ordered
            <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
    </ol>
  </ng-container>
</ng-container>

解决方案:

每个对象中都有一个用于说明子类型的属性,我将该属性命名为childrenType并与虚拟数据一起使用,您将不得不编写逻辑来动态添加该属性。

一旦完成:

您的递归组件中可以有类似的内容。

  <li>{{child.text}}</li>
    <ng-container *ngIf="child.children?.length > 0">
        <ul *ngIf="child.childrenType==='unordered-list-item'">
            <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
        </ul>
    <ol *ngIf="child.childrenType==='ordered-list-item'">
      <app-recursion *ngFor="let subChild of child.children" [child]="subChild"></app-recursion>
    </ol>
    </ng-container>

在此处查看修改后的示例:https://stackblitz.com/edit/angular-list-component-4kmets?file=src/app/app.component.ts

答案 1 :(得分:0)

更改或删除递归组件中的条件: * ngIf =“ nested.type ==='unordered-list-item'”

  <ng-container>
      <li>{{text}}</li>
    </ng-container>

答案 2 :(得分:0)

问题在于内部子级的类型是有序的(不是无序的)。 因此,只需将递归组件更改为:

<ng-container *ngIf="nested.type==='ordered-list-item'">
<li>{{text}}</li>
</ng-container>

答案 3 :(得分:0)

将数据从app-recursion数组发送到nested.children组件中。

所以app.component.html应该看起来像这样:

<ng-container *ngIf="nested.type==='unordered-list-item'">
    <li>{{nested.text}}</li>    
    <ul *ngIf="nested.children.length > 0">     
    <app-recursion [children]="nested.children"></app-recursion>
    </ul>
</ng-container>

然后在*ngFor中使用recursion.component.html

<ng-container >
  <li *ngFor="let child of children" >
      {{child.text}}
  </li>
</ng-container>