我是新手,我正在尝试使用ProxyProvider返回列表,这是main.dart中的代码
providers: [
FutureProvider<List<Mixer>>(
create: (_) => mixerdbService.retrieveMixers(),
initialData: <Mixer>[]),
ProxyProvider<List<Mixer>, List<int>>(update: (_, mixers, __) {
final List<int> ints = [];
for (var mixer in mixers) {
shipmentdbService
.retrieveNumberOfShipmentsByMixerId(mixer.id)
.then((value) => ints.add(value));
}
return ints;
}),这就是方法retrieveNumberOfShipmentsByMixerId
Future<int> retrieveNumberOfShipmentsByMixerId(String? mixerId) async {
QuerySnapshot<Map<String, dynamic>> snapshot = await _db
.collection("shipments")
.where("mixer_id", isEqualTo: mixerId)
.get();
return snapshot.docs.length;
}提供程序值是空列表。我认为proxyprovider的更新方法中存在一个错误。如果问题不清楚,请向我询问更多细节。
解决方案
step#1
FutureProvider<List<Mixer>>(
create: (_) => mixerdbService.retrieveMixers(),
initialData: <Mixer>[]),
ProxyProvider<List<Mixer>, Future<List<int>>>(
update: (_, mixers, __) async {
final List<int> ints = [];
for (var mixer in mixers) {
final value = await shipmentdbService
.retrieveNumberOfShipmentsByMixerId(mixer.id);
ints.add(value);
}
return ints;
}),step#2:使用FutureBuilder解决提供者的未来
FutureBuilder<List<int>>(
future: context.read<Future<List<int>>>(),
builder: (_, snapshot) {
if (snapshot.hasData &&
snapshot.data!.isNotEmpty &&
listOfMixers.isNotEmpty) {
return ListView.builder(
itemCount: listOfMixers.length,
itemBuilder: (_, index) {
return MixerCard(
mixer: listOfMixers[index],
numberOfShipments: snapshot.data![index]);
});
}
return Center(
child: CircularProgressIndicator(),
);
},
),这个解决方案是可以的,但是我仍然在寻找另一个不用FutureBuilder的解决方案。
发布于 2022-08-15 06:44:23
问题是,ProxyProvider正在返回一个列表,由于使用.then的异步调用,该列表尚未填充。
要解决这个问题,返回一个Future<List<int>>,并使更新函数async。如下所示:
ProxyProvider<List<Mixer>, Future<List<int>>>(
update: (_, mixers, __) async {
final List<int> ints = [];
for (var mixer in mixers) {
final value = await shipmentdbService
.retrieveNumberOfShipmentsByMixerId(mixer.id);
ints.add(value);
}
return ints;
}),解决方案1
然后添加另一个FutureProvider,如下所示:
FutureProvider<List<int>>(
create: (context) => context.read<Future<List<int>>>(),
initialData: [],
),这样就很容易使用了,就像:
final listOfMixers = context.watch<List<Mixer>>();
final listOfInts = context.watch<List<int>>();
return Scaffold(
body: listOfMixers.isNotEmpty && listOfInts.isNotEmpty // <- Here
? ListView.builder(
itemCount: listOfMixers.length,
itemBuilder: (context, index) {
return MixerCard(
mixer: listOfMixers[index],
numberOfShipments: listOfInts[index],
);
})
: const Center(
child: CircularProgressIndicator(),
),
);解决方案2
或者使用FutureBuilder将List<int>从Future中提取出来。如下所示:
FutureBuilder<List<int>>(
future: context.read<Future<List<int>>>(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return ErrorPage();
}
if (snapshot.data == null) {
return Center(child: CircularProgressIndicator());
}
final listLengths = snapshot.data;
// Do something with `listLengths`
}),https://stackoverflow.com/questions/73357432
复制相似问题