【发布时间】:2021-02-19 23:37:15
【问题描述】:
我正在构建一个井字游戏应用程序,我决定一起学习 BLoC for Flutter。 BlocBuilder 小部件有问题。
在我看来。每次 bloc 构建器小部件侦听的 Cubit/Bloc 发出新状态时,bloc 构建器都会执行此例程:
-
调用
buildWhen回调将先前状态作为previous参数传递,新发出的状态 作为current参数。 -
如果
buildWhen回调返回 true,则重新构建。 -
在重建期间调用
builder回调将给定上下文作为context参数传递,新发出的状态 作为state参数传递。此回调返回我们返回的小部件。
所以结论是buildWhen调用的current参数总是等于builder调用的state参数。但实际上它是不同的:
BlocBuilder<GameCubit, GameState>(
buildWhen: (previous, current) => current is SetSlotSignGameState && (current as SetSlotSignGameState).slotPosition == widget.pos,
builder: (context, state) {
var sign = (state as SetSlotSignGameState).sign;
// Widget creation goes here...
},
);
在builder 回调中,它抛出:
在构建 BlocBuilder
(dirty, state: _BlocBuilderBaseState #dc100): 类型“GameState”不是类型转换中“SetSlotSignGameState”类型的子类型 相关的导致错误的小部件是: BlocBuilder
我发出GameCubit 类中的状态的方法:
// [pos] is the position of the slot clicked
void setSlotSign(Vec2<int> pos) {
// Some code
emit(SetSlotSignGameState(/* Parameter representing the sign that is being placed in the slot*/, pos));
// Some code
emit(TurnChangeGameState());
}
简要介绍状态类型。 SetSlotSignGameState 在用户点击井字游戏网格中的插槽并且该插槽为空时发出。所以这种状态意味着我们需要在某个插槽中更改符号。 TurnChangeGameState 在我们需要轮到下一个玩家时发出。
临时解决方案。现在我通过将buildWhen 回调中的状态保存在 widget's 状态 的私有字段中,然后从构建器中使用它来修复它。 BlocListener 也有这个问题,但我可以将检查从 listenWhen 回调移动到 listen 回调。这种解决方案的缺点是非常不优雅和不方便。
【问题讨论】:
-
在您的代码中出现语法错误:
buildWhen: (previous, current) => current is SetSlotSignGameState && (current as SetSlotSignGameState).slotPosition == widget.pos) <-- THIS BRACKET HAS NO PAIR,。那是冒险吗? -
jorjdaniel,是的,这是我从代码编辑器中复制代码的错误,项目中的原始代码没有这个错误。很抱歉让您对此感到困惑。我将编辑删除错字的问题。
标签: flutter dart bloc flutter-bloc