我正在使用 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,才能在不同的情况下使用?