下面是代码。错误是当从类外部调用loadSounds函数返回空列表时。但是当loadSounds从loadcategories中调用时,它工作得很好,并返回一个包含Sound实例的列表。即使在loadSounds函数中打印sounds变量,也会打印一个空列表。
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', Instance of 'Sound', Instance of 'Sound', Instance of 'Sound']
我在类外访问它,如下所示:
final _sounds = await repository.loadSounds(event.categoryId);
从外部调用或从loadSounds函数打印时的输出如下:
[]
那么这里的问题是什么?我无法弄清楚为什么loadSounds函数在类内部从loadCategories调用时工作,而不是以任何方式。
如果在调用loadSounds()
之前不调用repository.loadCategories()
,则在您的声音变量中不会有任何内容,因为您仅在loadCateogries()
函数中分配值。
你的存储库变量是单例的吗?你在它上面调用了loadCategories吗?
同样,我不会这样写这行:
categories.map((c) => sounds.addAll(c.sounds)).toList();
toList()
方法并不真正有用,map函数应该更多地用于转换某些东西(例如,从字符串到Int映射)。
我会使用:
categories.forEach((c)=> sounds.addAll(c.sounds));
使用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);
where子句可能出错。因为条件不正确。试试这个:
return sounds
.where((sound) => sound.id[0] == categoryId)
.toList();