我有一个组件层次结构,看起来有点像这样:角2个变化探测阵列
@Component({
...
})
export class A {
constructor(private _serviceThatDeliversData: Service){}
getData(): Array<DataItem> {
return this._serviceThatDeliversData.getData();
}
}
HTML:
<b-selector [data]="getData()"></b-selector>
子组件:
@Component({
selector: 'b-selector'
...
})
export class B {
@Input() data: Array<DataItem>;
}
HTML:
<ul>
<li *ngFor="let item of data">
<c-selector [item]="item"></c-selector>
</li>
</ul>
所以我得到了一个从服务接收数据的父组件'A'。 serviceThatDeliversData每次从WebSocket接收数据时都会创建DataItem列表。然后将这个列表传递给'B',其中每个列表条目都被用作子组件的基础('C',这里我省略了C组件,因为它基本上只呈现输入数据'项目')。
我现在的问题如下: 由于每次服务获取更新时列表都会更改,因此C组件的所有列表+ B组件都是新创建的。我假设,因为DataItem列表完全改变Angular通知他们作为新的条目(?)和列表作为一个新的本身(?) 但实际上很可能是只有一个项目被添加或删除或只是一个字段在其中一个项目中更改。所以只需要删除/添加/更新一个C组件。
既然是这样,任何C组件中的视图中发生的任何动画都会在重新创建列表后停止并重新开始。这加上我想避免的一些其他副作用。
所以我的问题是,有没有办法让Angular只更新与实际内部改变的DataItem相关的C组件,以及添加到列表中或从列表中移除的那些组件,没有改变没有改变?
我搜索了一段时间,发现可以使用changeDetection:ChangeDetectionStrategy.OnPush,但是我还没有找到一个工作示例(具有更改数组和更改数组元素(内部)),这将帮助我解决问题。
我假设可以在'B'中存储列表副本,手动检查更改,然后对它们做出反应 - 也可以通过动画向用户发出信号,告知用户哪些条目已被删除或添加 - 但是,将需要一种方法来阻止Angular更新(重新创建)'B'和'C'组件。我使用相同的数组(清除它并用新条目重新填充它)可能会起作用。
但我仍然想知道这是否可以通过原始的Angular机制来实现。
看到[这个答案](https://stackoverflow.com/questions/45940888/how-to-prevent-calling-constructor-of-component-in-ngfor-directive/45942413#45942413) –