Flutter中使用Provider与AppWrite无法过滤数据问题求助
问题排查与修复
现有代码的疏漏点
数据库请求未应用过滤条件
在fetchData方法中,你定义了filters变量但并未将其传入database.listDocuments的参数中,导致每次请求都拉取全部数据(虽然后续做了本地过滤,但这一步属于无效操作,也会干扰问题排查)。修改方式是在listDocuments中添加filters参数:final response = await database.listDocuments( collectionId: 'posts', databaseId: 'app', filters: filters, // 新增这一行 );过滤逻辑未处理空字段
如果items中存在category字段为空或不存在的条目,调用item['category'].toLowerCase()会触发空指针异常,直接导致过滤结果为空。修改filterItemsByCategory方法,增加空值判断:void filterItemsByCategory(String category) { filteredItems = items .where((item) => item['category'] != null && item['category'].toLowerCase() == category.toLowerCase()) .toList(); }setSelectedCategoryIndex方法类型错误
该方法内部包含await fetchData(),但返回类型是void,会导致调用时无法等待异步操作完成,引发状态不同步。应修改为Future<void>:Future<void> setSelectedCategoryIndex(int index) async { selectedCategoryIndex = index; await fetchData(); }
更优的Provider数据过滤方案
建议将filteredItems改为计算属性(Getter),无需手动维护过滤后的列表,每次访问时自动根据当前items和selectedCategoryIndex计算结果,彻底避免遗漏过滤调用或状态不同步的问题:
修改DataProvider中的相关代码:
class DataProvider with ChangeNotifier { // 移除原来的filteredItems变量 // List<Map<String, dynamic>> filteredItems = []; // 新增计算属性 List<Map<String, dynamic>> get filteredItems { final currentCategory = categories[selectedCategoryIndex]; return items.where((item) => item['category'] != null && item['category'].toLowerCase() == currentCategory.toLowerCase()).toList(); } // 移除原来的filterItemsByCategory方法,以及所有手动调用该方法的地方 Future<void> fetchData() async { print('Fetching data'); final category = categories[selectedCategoryIndex]; print('Selected category: $category'); Map<String, dynamic> filters = {}; if (selectedCategoryIndex != 0) { filters = { 'category': { '\$eq': category, }, }; } final response = await database.listDocuments( collectionId: 'posts', databaseId: 'app', filters: filters, // 应用过滤条件 ); final documents = response.documents; items.clear(); items.addAll(documents.map((doc) { final decodedTitle = utf8.decode(base64.decode(doc.data['title'])); final decodedContent = utf8.decode(base64.decode(doc.data['content'])); return { ...doc.data, 'title': decodedTitle, 'content': decodedContent, }; })); print('Items: $items'); currentPage++; await saveDataToPrefs(); notifyListeners(); // 只需通知状态变化,filteredItems会自动计算 } Future<void> setSelectedCategoryIndex(int index) async { selectedCategoryIndex = index; await fetchData(); // 无需手动调用过滤,notifyListeners后UI会重新获取filteredItems } Future<void> loadDataFromPrefs() async { final savedData = prefs?.getStringList('items'); if (savedData != null) { items = savedData .map((item) => json.decode(item)) .cast<Map<String, dynamic>>() .toList(); notifyListeners(); // 通知状态变化即可 } } }
这种方案的优势:
- 无需手动维护
filteredItems状态,减少代码冗余和出错概率 - 状态变化时只需调用
notifyListeners(),UI会自动获取最新的过滤结果 - 逻辑更清晰,过滤规则集中在Getter中,便于后续修改
内容的提问来源于stack exchange,提问作者Maenda
相关产品推荐
相关产品推荐

