即使列表引用发生变化,如何重用 ngFor 的元素?

Posted

技术标签:

【中文标题】即使列表引用发生变化,如何重用 ngFor 的元素?【英文标题】:How to reuse the elements of ngFor even if the list reference changes? 【发布时间】:2016-11-05 01:15:50 【问题描述】:

我有一个 Angular 2 组件,它使用 *ngFor 呈现嵌套的数字数组。

@Component(
  selector: 'app',
  template: `
    <div *ngFor="let row in data">
      <div *ngFor="let curve in row">
        <chart [data]="curve">
      </div>
    </div>
  `,
  directives: [Chart],
)
export default class App 
  data: number[][][];

当我更改 data 时,Angular 会替换 &lt;chart&gt; 元素,即使新数组具有相同的维度。我只希望它更新图表的属性但保留元素(以便我可以为数据更改设置动画)。

Angular 替换元素是可以理解的,因为新数组是一个新的对象引用。但是我该如何规避呢?

【问题讨论】:

你能用ngForTrackBy吗? @Michael 这正是我想要的:trackByIndex(index: number, data: any) return index; 。请您回答一下好吗? +1 这个问题的浏览量和点赞量令人不安。例如,如果您忘记为列表项提供一个“关键”属性,ReactJS 会抛出一个嘶嘶声,以便可以经济地重新渲染列表。 【参考方案1】:

Working Plunker

平面数据结构

您可以将有关图表的元数据(标题、ID 等)与将发生变化和动画的实际数据点分开。

*ngFor 循环将使用元数据数组,每个图表组件将有一个 @Input(),该@Input() 将从单独的数据点对象中提取。

// Metadata
this.charts = [
  
    id: 1,
    title: 'Chart Title 1',
  ,
  
    id: 2,
    title: 'Chart Title 2',
  
];

// Data Points
this.chartData = 
  1: [87, 95, 121, 20, 60, 131, 10, 139, 128, 99],
  2: [56, 107, 107, 144, 43, 7, 67, 35, 141, 62]

模板

<div *ngFor="let chart of charts">
  <app-chart [inputMeta]="chart" [inputData]="chartData[chart.id]"></app-chart>
</div>

然后在您的图表组件中,您可以在更新数据点时使用ngOnChanges()lifecycle hook 来更新图表。

【讨论】:

【参考方案2】:

使用ngForTrackBy 应该对您有所帮助。

以下函数应更新元素属性,同时将元素保留在 DOM 中。

trackByIndex(index: number, data: any)  return index; 

【讨论】:

以上是关于即使列表引用发生变化,如何重用 ngFor 的元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何从可滚动容器中仅选择可见元素?

即使DOM发生变化,也要匹配元素

Windows phone 8 即使手机的主题发生变化,如何始终使用一个主题

为啥即使我没有将 vuex 状态绑定到任何 html 输入元素,我的 vuex 状态也会在更改组件级别状态时发生变化?

ngFor(Angular 9)中的动态模板引用变量

传递给函数后向量的大小发生变化