【发布时间】:2017-08-23 20:21:45
【问题描述】:
在处理不应销毁和重新初始化的视频组件数组或任何其他组件时,我将不胜感激有关 ngrx/store 和 Angular 2 的任何帮助。
这里的问题是每次数组中视频容器组件的状态发生变化(以不可变的方式),该组件被销毁并再次重新创建。 p>
另一个类似的用例是包装 jquery 图表组件的组件数组,不应在每次其配置状态更改时重新创建。
没有ngrx/store和immutable state,当array的item发生变化时,效果很好,视频容器不会重新初始化。但是当我通过ngrx/store使用不可变的方式管理状态时,需要创建全新的数组,如果某些视频参数(或图表配置)发生变化,也需要以不可变的方式更新数组中的对象.它可能看起来像这样:
[...container.slice(0, n), Object.assign({}, container[n], modifyObj), ...container.slice(n+1)]
但是 Angular 无法识别第 n 个组件不需要重新初始化,因为对象引用已更改。我不确切知道区域检测在内部是如何工作的,但是看起来当对象在列表中克隆时,引用丢失并且组件被破坏并创建了全新的组件(并且视频从头开始/ jquery 组件重新初始化)。
是否有可能更改数组项检测行为或任何其他方式以在数组中同时具有不可变状态和长寿命组件?
https://plnkr.co/edit/H6h1PSGAG4LNPBIIrKEy?p=preview
我已经创建了 plunker 示例。那里的内部计数器属性表示“视频正在播放”。该示例显示,当通过 Object.assign(...) 更改数组中元素的状态(此处为 id 为 1 的项目的“desc”属性)时,会创建全新的组件,并且计数器再次从 0 开始递增在它被销毁并再次重新初始化之后。
感谢您的帮助。
【问题讨论】:
-
您可以尝试将
changeDetection更改为onPush。在您的 plunker 中尝试显示实际的 ngrx 代码,因为您正在模仿相同的代码? -
我添加了 changeDetection 并重写了 plunker,以便它使用 ngrx/store(而不是计数器,我添加了带有自动播放功能的 youtube 视频)。
-
...结果是一样的——添加第4个视频并修改第1个视频状态后,再次重新加载第1个视频。 ngrx/store 没有问题,但状态不变性本身没有问题。当我在修改状态时在数组中创建新对象时,Angular 无法识别该对象表示与先前状态相同的组件 - 我可以想象 Angular 检测中的一些“按 id 比较”比较方法会有所帮助.
标签: arrays angular immutability ngrx-store