消费者 returns 空列表而不是实际数据

Consumer returns empty List instead of actual data

我正在使用 flutter 的提供程序包。 https://pub.dev/packages/provider

在 Appstart 上,我使用以下提供程序:

late Future<List<Art>> art;
late Future<List<Music>> music;
late Future<List<Furniture>> furniture;
late Future<List<Clothing>> clothing;
late Future<List<Flower>> flowers;
late Future<List<Interieur>> interieur;
late Future<List<Collectible>> allCollectibles;

  @override
  void initState() {
    super.initState();
    art = getAllArts();
    music = getAllMusic();
    furniture = getAllFurniture();
    clothing = getAllClothing();
    flowers = getAllFlowers();
    interieur = getAllInterieur();

    allCollectibles = () async {
      return [
        ...await art,
        ...await music,
        ...await furniture,
        ...await clothing,
        ...await flowers,
        ...await interieur,
      ];
    }();
  }
  @override
  Widget build(BuildContext context) {
    timeDilation = 1;

    return FutureBuilder(
      future: settings,
      builder: (context, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          return Center(child: CircularProgressIndicator());
        }

        return FutureProvider<List<Collectible>>(
                    create: (context) => allCollectibles, initialData: [],
                  ),});

后面我用这个consumer取回:

@override
  Widget build(BuildContext context) {
    return Consumer<List<Collectible>>(builder: (context, collectibles, child) {
      return sendCollectibleDataFull(collectibles),
    });
  }

方法 sendCollectibleDataFull 中的列表有时存在有时不存在。 如果它在通话时为空,它将保持为空。

我已经更新到 nullsafety,因此 initialData: [], 成为强制性的。在那之前,我总是从这里得到一个列表。

我可以告诉我的 Consumer/Provider 在检索数据之前等待数据吗?

嗨@lellek,欢迎。

好的,我想指出几件事。

您正在使用默认的 FutureProvider 构造函数和创建回调,但实际上您提供的值已经存在。

        return FutureProvider<List<Collectible>>(
                    create: (context) => allCollectibles, initialData: [],
                  ),});

如果您已经有一个值并且您没有使用 Provider 创建它,您应该使用 .value 构造函数。

但是,您可以将默认构造函数与 create 回调一起使用,并在那里完成所有工作,而不是让 StatefulWidget 完成一些工作(除非您在这里只需要这些实例作为嗯)。

这没有经过测试,但它应该看起来像这样:

FutureProvider<List<Collectible>>(
  create: (context) async {
    /// get collectibles in parallel
    final List<List<Collectible>> results = await Future.wait([
      getAllArts(), 
      getAllMusic(), 
      getAllFurniture(), 
      getAllClothing(), 
      getAllFlowers(), 
      getAllInterieur(),
    ]);

    /// flatten the results
    final allCollectables = [for (final collectibles in results) ...collectibles];

    return allCollectables;
  }, 
  initialData: [],
)

Can I tell my Consumer/Provider to await the data before I retreive it?

不,关键是初始值,在本例中 [],将从提供者处获得,并且树将在未来解决时更新。