Потребительский триггер Flutter MultiProvider — как предотвратить множественные перестроения?

#flutter #dart #provider

#флаттер #dart #поставщик

Вопрос:

 Widget build(BuildContext context) {
repo = Provider.of<ProductSessionRepository>(context);
shopInfoRepository = Provider.of<ShopInfoRepository>(context);
psValueHolder = Provider.of<PsValueHolder>(context, listen: false);

final Widget _expansionTileTitleWidget = Text(
    Utils.getString(context, 'detail_info_tile__session_info'),
    style: Theme.of(context).textTheme.subtitle1);

return MultiProvider(
    providers: <SingleChildWidget>[
      ChangeNotifierProvider<RegisteredProductSessionProvider>(
          lazy: false,
          create: (BuildContext context) {
            final RegisteredProductSessionProvider provider =
                RegisteredProductSessionProvider(
                    repo: repo, userId: psValueHolder.loginUserId);
            if (widget.isNavRegistered) {
              provider.getRegisteredProductSessionList(widget.productId);
            }
            return provider;
          }),
      ChangeNotifierProvider<EnrolledProductSessionProvider>(
          lazy: false,
          create: (BuildContext context) {
            final EnrolledProductSessionProvider provider =
                EnrolledProductSessionProvider(
                    repo: repo, userId: psValueHolder.loginUserId);
            if (!widget.isNavRegistered) {
              provider.getEnrolledProductSessionList(widget.productId);
            }
            return provider;
          }),
      ChangeNotifierProvider<ProductSessionProvider>(
          lazy: false,
          create: (BuildContext context) {
            final ProductSessionProvider provider = ProductSessionProvider(
                repo: repo, userId: psValueHolder.loginUserId);
            productSessionProvider = provider;
            return provider;
          }),
      ChangeNotifierProvider<ShopInfoProvider>(
          lazy: false,
          create: (BuildContext context) {
            final ShopInfoProvider provider = ShopInfoProvider(
                repo: shopInfoRepository,
                psValueHolder: psValueHolder,
                ownerCode: 'HomeDashboardViewWidget');
            provider.loadShopInfo();
            return provider;
          }),
    ],
    child: Consumer3<ShopInfoProvider, EnrolledProductSessionProvider,
            RegisteredProductSessionProvider>(
        builder: (context, shopInfoProvider, enrolledProductSessionProvider,
            registeredProductSessionProvider, Widget child) {
      if (widget.isNavRegistered) {
        sessionList = registeredProductSessionProvider
            .registeredProductSessionList.data;
      } else {
        sessionList =
            enrolledProductSessionProvider.enrolledProductSessionList.data;
      }
      sessionList.sort((a, b) => a.compareTo(b));

      //added future builder to wait for the session status update
      return FutureBuilder<List<Session>>(
        future: WidgetUtils.checkAndUpdateSessionStatus(sessionList,
            productSessionProvider, shopInfoProvider.shopInfo.data),
        builder:
            (BuildContext context, AsyncSnapshot<List<Session>> snapshot) {
          if (snapshot.hasData) {
            //if (snapshot.connectionState != ConnectionState.waiting amp;amp;!snapshot.hasError) {
            sessionList = snapshot.data; //consolidated sessionList

            if (sessionList.length > 0) {
              return Card(
                elevation: 0.0,
                child: PsExpansionTile(
                  initiallyExpanded: false,
                  title: _expansionTileTitleWidget,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.only(
                          bottom: PsDimens.space10,
                          left: PsDimens.space10,
                          right: PsDimens.space10),
                      child: sessionList.length > 0
                          ? Column(
                              crossAxisAlignment:
                                  CrossAxisAlignment.stretch,
                              children: <Widget>[
                                Center(
                                    child: _buildSessionDataTable(context)),
                              ],
                            )
                          : Container(child: Text('None')),
                    )
                  ],
                ),
              );
            } else {
              return Container();
            }
          } else {
            return Container();
          }
        },
      );
    }));
  

Как отмечалось выше, у меня многопоставщик с несколькими потребителями. В блоке кода Consumer3 у меня есть FutureBuilder, поскольку у меня есть метод асинхронного обновления статуса сеанса checkAndUpdateSessionStatus() . Блок кода consumer3 запускается несколько раз, и я думаю, что такова природа потребительской модели MultiProvider. Проблема в том, что прямо сейчас функция checkAndUpdateSessionStatus() также вызывается несколько раз, и я хочу, чтобы это было вызвано один раз. Возможно, я могу использовать StreamBuilder, и мне все еще нужно иметь async checkAndUpdateSessionStatus() .

Я довольно новичок в flutter. Я видел много элементов StackOverfow о том, как предотвратить сборку с несколькими сборками, и ни один из них не решает мою основную проблему (мне нужен MultiProvider, но я не хочу запускать потребителей несколько раз, и внутри потребителя у меня есть асинхронный процесс, который не должен обрабатываться с несколькими потребительскими триггерами).

Любое решение или альтернативное решение действительно помогло бы мне и заранее благодарит.

Комментарии:

1. Я в той же лодке. Вы можете попробовать Selector (что я пробовал один раз, но я знал, что я делаю меньше, чем сейчас, поэтому попробую еще раз). Кроме того, Provider было несколько довольно интересных обновлений с версии 4.1.0. Например, в версии 4.2.0 добавлен параметр builder для MultiProvider. Я также собираюсь изучить это. Вот сообщение с некоторыми объяснениями и примерами .