My project includes a component hierarchy structured like this:
@Component({
...
})
export class A {
constructor(private _serviceThatDeliversData: Service){}
getData(): Array<DataItem> {
return this._serviceThatDeliversData.getData();
}
}
html:
<b-selector [data]="getData()"></b-selector>
Child component:
@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>
In my application, the parent component 'A' retrieves data from a service called serviceThatDeliversData. This service generates a list of DataItems every time it receives data from a websocket. The list is then passed down to child component 'B', where each list entry serves as a basis for subcomponents ('C').
The issue I am facing is that whenever the service updates the list, all C components along with B are recreated. It seems like Angular treats the updated list as entirely new entries, even if only one item has been added or removed, or if a field within an item has changed.
This restart causes any ongoing animations in the view of C components to stop and start again when the list is recreated. This interruption, along with other side effects, needs to be avoided.
Would it be possible for Angular to update only those C components related to a DataItem that has internally changed, as well as those that have been added or removed from the list? Is there a way to leave unchanged components untouched?
I have researched using changeDetection: ChangeDetectionStrategy.OnPush but haven't found a suitable example that addresses my specific problem of dealing with changing arrays and elements within them.
One potential solution could involve storing a copy of the list in 'B', manually checking for changes, and reacting accordingly—potentially including an animation to indicate additions or removals. However, this approach would require preventing Angular from updating (recreating) 'B' and 'C' components altogether. Perhaps utilizing the same array by clearing it and repopulating it with new entries might offer a workaround.
Nevertheless, I am curious to know if there exists a raw Angular mechanism that could achieve this goal.