使用新查询重新访问时已创建的嵌套 FutureBuilder 快照仍然存在
Posted
技术标签:
【中文标题】使用新查询重新访问时已创建的嵌套 FutureBuilder 快照仍然存在【英文标题】:Nested FutureBuilder's snapshot that already create still there when re-visit with new query 【发布时间】:2020-10-11 14:45:10 【问题描述】:有材料应用程序查询数据库以显示类别中的项目。
-
页面 [类别] - 选择类别 A(传递的参数作为类别 id A)
页面 [Items] - (仅从数据库中查询项目 A)ListView.builder 正确显示类别 A 的项目
然后点击返回
页面 [Category] -> 选择类别 B(传递的参数作为类别 id B)
页面 [Items] ->(仅从数据库中查询到项目 B)ListView.builder 意外显示类别 A 和 B 的项目
注意:我需要调用条件未来函数来显示项目,然后我调用 FutureBuilder 作为 StreamBuilder 的嵌套。在我们需要一个项目类别之前,它工作正常。导致 StreamBuilder 的结果可能会有所不同。然后观察到 FutureBuilder 的快照没有清理好。
Widget _buildBody(BuildContext context)
return StreamBuilder<QuerySnapshot>(
stream: firestoreInstance.collection('items').where("category", isEqualTo: widget.categoryId).snapshots(),
builder: (context, snapshot1)
if (!snapshot1.hasData) return LinearProgressIndicator();
else return _buildList(context, snapshot1.data.documents);
,
);
Widget _buildList(BuildContext context, List<DocumentSnapshot> docSnapshot)
return FutureBuilder <List<ItemsRecord>> (
future: getDetailsOfEachItem(context, docSnapshot),
builder: (context, snapshot2)
if (snapshot2.hasData == true)
return new ListView.builder(
itemCount: snapshot2.data.length,
itemBuilder: (BuildContext ctxt, int index)
return _buildListItem(context, snapshot2.data[index]);
);
else
return Container(hieght: 0);
);
通过调试查询(By StreamBuilder)项目的数据库结果是正确的。只有 B 可用。
Debugging result of step above.
snapshot1 => Category A => 15 items
snapshot1=> Category B => 6 items
但是看起来FutureBuilder中的项目A在快照中仍然存在。
Debugging result of step above.
snapshot2 => Category A => 15 items
snapshot2 => Category A & B => 21 items (Unexpected !)
请帮助建议我如何在 FutureBuilder 的快照 2 中删除意外项目 A。
我尝试添加 snapshot2.data.clear();但是当 hasData 不为真时,数据似乎为空,在 ConnectionState 等待时也是如此。
尝试参考snapshot2.requireData而不是snapshot2.data,结果也一样。
【问题讨论】:
请添加更多代码和上下文,我们无法猜测您还做了什么 @AlbertoMiola 添加了多行代码和解释,希望你能理解我的代码和当前的调试结果。 【参考方案1】:尝试添加forEach手动删除找到的异常:迭代期间并发修改:'_GrowableList'的实例(长度:21)
搜索然后意识到 dart 有一个选项,在交互过程中我们可以标记要删除的项目,然后使用 removeWhere 在批量操作中删除它们。 Ref
这段代码对我来说很好用。
Widget _buildList(BuildContext context, List<DocumentSnapshot> docSnapshot)
return FutureBuilder <List<ItemsRecord>> (
future: getDetailsOfEachItem(context, docSnapshot),
builder: (context, snapshot2)
if (snapshot2.hasData == true)
List<ItemsRecord> records = snapshot2.data;
List toRemove = [];
records.forEach((record)
if (record.category != widget.categoryId)
toRemove.add(record);
);
records.removeWhere( (e) => toRemove.contains(e));
return new ListView.builder(
itemCount: snapshot2.data.length,
itemBuilder: (BuildContext ctxt, int index)
return _buildListItem(context, snapshot2.data[index]);
);
else
return Container(hieght: 0);
);
感谢 Alberto Miola,我认为他的问题促使我尝试深入研究问题进行解释,这让我简单地找到了答案。实际上,我们应该称之为解决方法。
【讨论】:
以上是关于使用新查询重新访问时已创建的嵌套 FutureBuilder 快照仍然存在的主要内容,如果未能解决你的问题,请参考以下文章
使用 prisma,如何从嵌套写入中访问新创建的记录(先更新,然后在其中创建)