Flutter嵌套列表搜索后清空查询无法恢复初始状态问题求助
问题原因
- Dart中对象传递是引用传递,你的
list和备份用的list2存储的是同一批Categorie对象的内存引用 - 原搜索逻辑中直接对
categorie.service执行了clear()、addAll()操作,相当于直接修改了list2中存储的原始对象的service数组,导致原始备份数据被破坏 - 清空搜索词调用
list.addAll(list2)时,拿到的已经是被修改过的残缺数据,自然无法恢复初始状态
修复方案
核心原则:list2作为只读的原始数据源,全程不允许修改其内部的任何对象属性,搜索时仅基于原始数据生成新的副本用于展示。
修复后的代码
filterSearchResults(String query) { if (query.isNotEmpty) { List<Categorie> resultSearchCategorie = []; // 直接从原始备份list2遍历,不修改原数据对象 for (var categorie in list2) { List<Service> matchedServices = []; for (var service in categorie.service!) { if (service.name!.toLowerCase().contains(query.toLowerCase())) { matchedServices.add(service); } } // 不需要过滤空分类可以删掉这个if判断 if (matchedServices.isNotEmpty) { // 创建新的Categorie副本,完全不修改原始对象的属性 resultSearchCategorie.add(Categorie( name: categorie.name, service: matchedServices, // 请补充Categorie类的其他属性赋值,不要遗漏 )); } } setState(() { list.clear(); list.addAll(resultSearchCategorie); }); } else { setState(() { list.clear(); // 从原始备份恢复时也做一层拷贝,避免后续操作污染原始数据 for (var categorie in list2) { list.add(Categorie( name: categorie.name, service: List.from(categorie.service!), // 请补充Categorie类的其他属性赋值,不要遗漏 )); } }); } }
优化说明
- 如果你的
Categorie、Service类是用freezed生成的不可变类,可以直接调用copyWith生成新对象,代码会更简洁 - 代码中额外把查询词也转成了小写,避免大小写差异导致的匹配遗漏
- 默认过滤了没有匹配到服务的空分类,不需要该逻辑直接删除
if (matchedServices.isNotEmpty)判断即可
内容的提问来源于stack exchange,提问作者songcraft
相关产品推荐
相关产品推荐

