Flutter 颤振中的不可变集合与可观测集合

Flutter 颤振中的不可变集合与可观测集合,flutter,dart,Flutter,Dart,当将颤振与实时数据库(如Firebase数据库)一起使用时,不仅要知道集合已更新,而且要知道其确切位置,这是非常有益的。例如,显示一个漂亮的项目,或者根据更新的项目触发一些附加事件。Dart已经有了一个传递事件的工具 一个典型的例子是使用,但它粘在Firebase上,不支持过滤和排序(在非常基本的之外)。我正在寻找一个更通用的解决方案,它将允许在数据库(通知项更改/插入/删除)和前面提到的AnimatedList之间插入一些逻辑,后者需要相同的事件 最近的趋势似乎是支持不可变的集合,例如,这在D

当将颤振与实时数据库(如Firebase数据库)一起使用时,不仅要知道集合已更新,而且要知道其确切位置,这是非常有益的。例如,显示一个漂亮的项目,或者根据更新的项目触发一些附加事件。Dart已经有了一个传递事件的工具

一个典型的例子是使用,但它粘在Firebase上,不支持过滤和排序(在非常基本的之外)。我正在寻找一个更通用的解决方案,它将允许在数据库(通知项更改/插入/删除)和前面提到的AnimatedList之间插入一些逻辑,后者需要相同的事件

最近的趋势似乎是支持不可变的集合,例如,这在Dart中很有意义,因为对象创建就是这样。然而,不可变的集合并没有一种方法来判断哪些项已经更改,它们只是传递一个新集合。这种方法还使得将一些本地信息附加到项目上变得困难,例如用户多选择项目时的“选定”位,或自定义排序。因为,项目是不可变的,它们的引用(又名指针,又名对象ID)不断变化

另一种解决方案是实现一种可观察列表,如what offers,但它的作者似乎不再相信它的流行。那么,您采取什么方法来创建动画、过滤、排序、选择支持列表,并以实时数据库为支持

然而,不可变的集合并没有一种方法来判断哪些项已经更改,它们只是传递一个新集合

一些伪代码:
(旧集合)-(新集合)=(已更改的内容)
-也以另一种方式工作

这种方法还使得将一些本地信息附加到项目上变得困难,例如用户多选择项目时的“选定”位,或自定义排序

扩展所说的“项”并添加一个属性
选定的
(或
顺序
,或您想要的任何其他可用信息),然后只需使用正确设置的这些属性构建新列表

这几天有很多关于颤振的状态管理问题,所以为了避免重复我的话,我宁愿把你链接到

编辑:

我只想插入一个关于
(旧集合)-(新集合)=(更改的内容)
的实际示例:

基本上,这是如何在比较两个包含密切相关元素的列表时查看更改的内容

List currentState=[…];
List nextState=[…];
列表addedItems=nextState.where((e)=>!currentState.contains(e)).toList(),
List removedItems=currentState.where((e)=>!nextState.contains(e)).toList();
doSomethingWith(增编);
doSomethingElseWith(移除的项目);
当然,您应该记住,这些列表应该具有很强的可比性,即对于Dart的特定情况,您可以使用
build\u value
equalable


我还上传了一个,带有一个纯Dart项目示例。非常欢迎您对代码做任何您想做的事情。

鉴于数据库首先给出的是“更改的内容”,因此伪代码的效率非常低。而找到之前的物品位置来正确设置动画则更加困难。扩展项不是一个选项,原因相同:一旦新数据到达,任何附加状态都将被覆盖。我已经阅读了关于状态管理的答案,这很好,但没有告诉任何新的内容。不幸的是,这对回答我的问题毫无帮助。你不能保留一个对旧状态的引用吗?当你从数据库收到数据(新状态)时,就把它和那个引用进行比较。然后只销毁对旧数据的引用(如果它是某种可侦听的),或者让GC完成它的工作。我还建议使用而不是内置值(尽管它们的内置序列化非常好)来比较同一类的实例。@J.Williams我已经用一些更实用的代码更新了我的答案。我还看了动画列表,可以确认它有点乱。它将声明性逻辑与命令式逻辑(即AnimatedListState的removeItem()和insertItem())混合在一起。。。但最后,我的评论中的同样逻辑应该适用于您的用例。谢谢,这是解决这个问题的可行方法,但很难理解。它有相当多的缺点:任何字段更改都会丢失项的整个状态,因为它被“删除”;我们放弃了方便高效的数据库添加/删除/更改事件;分页将效率低下,因为重新计算了整个列表(O(n^2)个完整比较);AnimatedList操作索引,因此它将更加复杂。我正在寻找一些可重用的东西,在那里我不必构建大量的样板文件。