为什么函数在 Flutter 中返回一个空列表

问题描述

所以这是代码。错误是从类外部调用 loadSounds 函数时返回一个空列表。但是当从 loadcategories 调用 loadSounds 时,它工作正常并返回一个包含 Sound 实例的列表。即使在 loadSounds 函数中打印声音变量也会打印一个空列表。

class AudioRepository {
  List<Category> categories = <Category>[];
  List<Sound> sounds = <Sound>[];

  Future<String> _loadCategoriesAsset() async =>
      await rootBundle.loadString(Assets.soundsJson);

  Future<List<Category>> loadCategories() async {
    if (categories.isNotEmpty) {
      return categories;
    }

    String jsonString = await _loadCategoriesAsset();
    categories.clear();
    categories.addAll(categoryFromJson(jsonString));
    categories.map((c) => sounds.addAll(c.sounds)).toList();
  
    loadSounds('1');
    return categories;
  }

  Future<List<Sound>> loadSounds(String categoryId) async {
    print(sounds);
    return sounds
        .where((sound) => sound.id.substring(0,1) == categoryId)
        .toList();
  }
}

从 loadCategories 调用时的输出如下:

[Instance of 'Sound',Instance of 'Sound',Instance of 'Sound']

我在课外访问它,如下所示:

final _sounds = await repository.loadSounds(event.categoryId);

从外部调用或从 loadSounds 函数打印时的输出如下:

[]

所以这里有什么问题。我无法弄清楚为什么当从类内的 loadCategories 调用时 loadSounds 函数会起作用,而不会以任何其他方式调用。

解决方法

使用 provider 和 ChangeNotifier 是最好的方法。 你的代码会像这样

class AudioRepository extends ChangeNotifier {
  List<Category> categories = <Category>[];
  List<Sound> sounds = <Sound>[];

  Future<String> _loadCategoriesAsset() async =>
      await rootBundle.loadString(Assets.soundsJson);

  Future<List<Category>> loadCategories() async {
    if (categories.isNotEmpty) {
      return categories;
    }

    String jsonString = await _loadCategoriesAsset();
    categories.clear();
    categories.addAll(categoryFromJson(jsonString));
    categories.map((c) => sounds.addAll(c.sounds)).toList();

    //notify listeners
    notifyListeners();
    ////
    loadSounds('1');
    return categories;
  }

  Future<List<Sound>> loadSounds(String categoryId) async {
    print(sounds);
    return sounds
        .where((sound) => sound.id.substring(0,1) == categoryId)
        .toList();
  }
}

要从外部检索数据,应将以下代码放在 Build() 方法中。

final _arp = Provider.of<AudioRepository>(context,listen: true);

print(_arp._sounds);
,

如果您在调用 repository.loadCategories() 之前不调用 loadSounds(),您的声音变量中将不会有任何内容,因为您仅在 loadCateogries() 函数中赋值。

您的存储库变量是单例变量吗?您是否在其上调用了 loadCategories?

另外,我不会像这样写这一行:

categories.map((c) => sounds.addAll(c.sounds)).toList();

toList() 方法不是很有用,应该更多地使用 map 函数来转换某些内容(例如 String 到 Int 的映射)。

我会使用:

categories.forEach((c)=> sounds.addAll(c.sounds));
,

可能是 where 子句中的错误。因为条件不对。 试试这个:

return sounds
        .where((sound) => sound.id[0] == categoryId)
        .toList();

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...