You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中使用Provider与AppWrite无法过滤数据问题求助

问题排查与修复

现有代码的疏漏点

  1. 数据库请求未应用过滤条件
    在fetchData方法中,你定义了filters变量但并未将其传入database.listDocuments的参数中,导致每次请求都拉取全部数据(虽然后续做了本地过滤,但这一步属于无效操作,也会干扰问题排查)。修改方式是在listDocuments中添加filters参数:

    final response = await database.listDocuments(
      collectionId: 'posts',
      databaseId: 'app',
      filters: filters, // 新增这一行
    );
    
  2. 过滤逻辑未处理空字段
    如果items中存在category字段为空或不存在的条目,调用item['category'].toLowerCase()会触发空指针异常,直接导致过滤结果为空。修改filterItemsByCategory方法,增加空值判断:

    void filterItemsByCategory(String category) {
      filteredItems = items
          .where((item) => 
              item['category'] != null && 
              item['category'].toLowerCase() == category.toLowerCase())
          .toList();
    }
    
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 08:22:50