即使列表引用发生变化,如何重用 ngFor 的元素?
How to reuse the elements of ngFor even if the list reference changes?
我有一个 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 会替换 <chart>
元素,即使新数组具有相同的维度。我希望它只更新图表的属性但保留元素(以便我可以为数据更改设置动画)。
Angular替换元素是可以理解的,因为新数组是一个新的对象引用。但是我该如何避免呢?
Working Plunker
平面数据结构
您可以将有关图表的元数据(标题、ID 等)与将发生变化和动画的实际数据点分开。
*ngFor
循环将使用元数据数组,并且每个图表组件都会有一个 @Input()
,它将从单独的 object 数据点中提取。
// 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 来更新图表。
使用 ngForTrackBy 应该能帮到你。
以下函数应更新元素属性,同时将元素保留在 DOM。
trackByIndex(index: number, data: any) { return index; }
我有一个 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 会替换 <chart>
元素,即使新数组具有相同的维度。我希望它只更新图表的属性但保留元素(以便我可以为数据更改设置动画)。
Angular替换元素是可以理解的,因为新数组是一个新的对象引用。但是我该如何避免呢?
Working Plunker
平面数据结构
您可以将有关图表的元数据(标题、ID 等)与将发生变化和动画的实际数据点分开。
*ngFor
循环将使用元数据数组,并且每个图表组件都会有一个 @Input()
,它将从单独的 object 数据点中提取。
// 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 来更新图表。
使用 ngForTrackBy 应该能帮到你。
以下函数应更新元素属性,同时将元素保留在 DOM。
trackByIndex(index: number, data: any) { return index; }