0

我正在使用 GraphQL、Provider、Bloc 和 Equatable。我的应用程序有一个 PageView,它的孩子每个都提出一个不同的选择题。位于包含小部件中的按钮调用pageController.nextPage并触发 GraphQL 突变,该突变使用答案更新数据库。问题是Flutter重建了PageView,我想那是因为我在它上面使用了BlocBuilder。

这是该附近的 Widget 树的简化视图:

BlocProvider<GraphQLBloc>
└QuestionsWidget
 └BlocBuilder<GraphQLBloc, GraphQLStates>
  └QuestionsStepperWizard
   └PageView

我将 BlocProvider 放在 QuestionsWidget 和 BlocBuilder<GraphQLBloc, GraphQLStates> 上面 QuestionsStepperWidget 的原因是因为我在构建 PageView 问题列表之前测试了 GraphQL 获取请求的状态,这似乎是 Bloc、BlocProvider 和块生成器:

if (state is HasuraLoadingInProgress) {
  …
} else if (state is HasuraLoadDataFail) {
  …
} else {
  // retrieve the data
  data = (state as HasuraLoadDataSuccess).data['unanswered_questions'];
  if (data != null) {
    …
    // pass the questions to the QuestionsStepperWizard widget
    // where the list of question screens is built 
    // and PageView can page between each
    return QuestionsStepperWizard(
      questions: questions,
      user: widget.user,
      show: pushAndPop,
    );
  }
}

但这显然不是运行突变的好方法,因为我不希望在从更深的小部件(例如 QuestionsStepperWizard)运行 GraphQL 突变的过程中重建小部件树:

if (answer > 0) {
    // the following event redraws all widgets under BlocProvider<GraphQLBloc>
    // NOT what I want
    onPressed: () {
      BlocProvider.of<GraphQLBloc>(context).add(
        MutateGraphQLData(
            query: mutations.addUserAnswer,
            variables: <String, dynamic>{
              'answer': answer.toString(),
              'question_id': currentQuestion.guid,
              'user_id': user.uid,
            }),
      );
      pageController.nextPage(
        duration: Duration(milliseconds: 300),
        curve: Curves.easeOut);
    }
}

相反,如果我将BlocProvider.of(context).add(...)替换为对简单 GraphQL 服务类的简单调用,则一切正常。数据库已更新,pageController.nextPage将下一个问题带入视图。

我想知道 Bloc 是否可以用来提供服务,如果可以,如何?或者问题是,是否值得创建一个 GraphQLBloc?还是我的代码必须有 GraphQLBloc 和 GraphQLService,才能在不同的情况下使用?

4

0 回答 0