Jan Havlíček
Jan Havlíček

Reputation: 21

Angular 2 + ngrx/store - avoid reinitialization of components in array

I would appreciate any help with the ngrx/store and Angular 2 when working with arrays of video components or any other components, that shouldn't be destroyed and reinitialized.

The issue here is that each time the state of video container component in array changes (in the immutable way), this component is destroyed and recreated again.

Another similar use-case is the array of components wrapping jquery chart component, that shouldn't be recreated each time its configuration state changes.

Without the ngrx/store and immutable state, when the item of array is changed, it works well and the video container is not reinitialized. But when I use immutable way of managing state with ngrx/store, the brand new array needs to be created and if some video parameter (or chart configuration) changes, it is necessary to update the object in the array in the immutable way as well. It could look like this:

[...container.slice(0, n), Object.assign({}, container[n], modifyObj), ...container.slice(n+1)]

But Angular does not recognise that the n-th component is not need to be reinitialized because the object reference has changed. I don't know exactly, how the Zone detection works internally, but it looks like when the object is cloned in the list, the reference is lost and the component is destroyed and brand new component is created (and video starts from the beginning/jquery component reinitializes).

Is there any possibility to change the array item detection behavior or any other way to have both immutable state and long lived components in arrays?

https://plnkr.co/edit/H6h1PSGAG4LNPBIIrKEy?p=preview

I've created plunker example. The internal counter property there represents the "video is playing". The example shows that when the state of element in array is changed via Object.assign(...) (here the "desc" attribute of the item with id 1), brand new component is created and the counter starts incrementing from 0 again after it is destroyed and reinitialized again.

Thanks for any help.

Upvotes: 1

Views: 1035

Answers (1)

Jan Havlíček
Jan Havlíček

Reputation: 21

Oh, I solved it. It has nothing with ngrx/store. It is just, how the Angular tracks changes in ngFor.

The strategy can be changed with "trackBy" parameter in ngFor. I can now create the function, that track changes by object's identifier instead its reference. If some else has the same issue, more information about "trackBy" is described here:

http://blog.angular-university.io/angular-2-ngfor/#howtousetrackby

Upvotes: 1

Related Questions