代理提供程序 - 努力使用它返回列表<int>



我是flutter的新手,我正试图使用ProxyProvider根据List返回List这是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;
}),

该方法按混合器ID 检索发货数量

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;
}

提供程序值是一个空列表。我认为代理提供者的更新方法中的逻辑存在错误。如果问题不清楚,请询问我有关的更多详细信息

解决方案

步骤#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;
}),

步骤#2:使用FutureBuilder从提供程序解析Future

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的解决方案。

问题是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

或者使用FutureBuilderFuture中取出List<int>。类似以下内容:

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`
}),

最新更新