Angular:当替换父列表时,如何将组件状态保留在嵌套组件树中

问题描述 投票:1回答:2

我正在尝试设置一个包含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

期望:

我希望扩展/崩溃状态在列表更新时保持不变。

angular nested components
2个回答
1
投票

这就是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


1
投票

您可以将trackByFunction传递给ngFor-directive。因此,您的项目的ID应该是唯一的(两次2.2)。以下是您的代码的一个工作示例:https://stackblitz.com/edit/angular-nested-components-updated-fprktk

© www.soinside.com 2019 - 2024. All rights reserved.