首页 > 解决方案 > Angular:替换父列表时如何在嵌套组件树中保持组件状态

问题描述

我正在尝试设置一个具有 3 层嵌套子级的展开/折叠列表。每次单击项目都会刷新列表。“扩展”状态当前存储在“项目”组件中,因此当列表被替换时,该组件被破坏并失去“扩展”状态。

我尝试过的事情

我通过将“组”提取到它自己的组件中解决了类似的问题,但那是在一个没有嵌套的列表中。我似乎无法在“高于”整个列表的级别提取此“扩展”标志

这将是一个大小相当合理的列表,因此我 可以尝试更新列表而无需“替换”它,但这听起来像是灾难的秘诀。

样本项目数据

{
  "Id": "2",
  "Children": [
    {
      "Id": "2.1",
      "Children": [
        {
          "Id": "2.2",
          "Children": []
        }
      ]
    },
    {
      "Id": "2.2",
      "Children": []
    }
  ]
}

然后我递归地设置组件

# item.component.html

<li>
  <div *ngIf="item.Children.length === 0">{{item.Id}}</div>

  <div *ngIf="item.Children.length > 0">
    <button (click)="expanded = !expanded">{{item.Id}}</button>
    <ul *ngIf="expanded">

      <item
        *ngFor="let subItem of item.Children"
        [item]="subItem">
      </item>

    </ul>
  </div>
</li>

孤立的例子

我在 StackBlitz 上设置了一个独立的示例:

https://stackblitz.com/edit/angular-nested-components-updated-xavyfe

期望:

我希望即使更新列表也能保持展开/折叠状态。

标签: angularnestedcomponents

解决方案


trackBy就是为了。有了它,Angular 只会刷新需要刷新的内容。我假设Id这里是独一无二的。

在模板中:

      <item
        *ngFor="let subItem of item.Children; trackBy: trackById"
        [item]="subItem">
      </item>

在 TS 中:

  trackById = (item) => item.Id;

https://stackblitz.com/edit/angular-nested-components-updated-ng4gac


推荐阅读