Flutter BLoC库:将TextEditingController对象放在哪里?是在State中、在BLoC/Cubit类中还是在widget中?

15

使用BLoC库时,我们将所有变量存储在状态类中。但是,我们应该把不变的但值会发生变化的TextEditingController放在哪里呢?

假设我有一个像这样的状态类(仅作为示例):

@freezed
abstract class EditItemState with _$EditItemState {
  const factory EditItemState.updated({
    TextEditingController titleController,
    ShoppingItem shoppingItem,
  }) = _ShoppingListLoaded;
}

以及 Cubit 类:

class EditItemCubit extends Cubit<EditItemState> {
  EditItemCubit() : super(EditItemState.updated());

  Future<void> titleUpdated() async {
    emit(
      EditItemState.updated().copyWith(
        shoppingItem: state.shoppingItem.copyWith(
          title: state.titleController.text,
        ),
      ),
    );
  }
}

因此Cubit类的逻辑看起来很混乱。我建议将这样的控制器直接放在小部件或BLoC/Cubit类中。这是正确的方法吗?

4个回答

24

这里有人向库的作者问了同样的问题,而Felix Angelov(flutter_bloc的作者)的答案是:

我强烈建议不要将TextEditingController作为bloc的一部分进行维护。Blocs应该是跨平台的,并且不依赖于Flutter。如果您需要使用TextEditingController,我建议创建一个StatefulWidget并将其作为State类的一部分进行维护。然后,您可以通过BlocListener响应状态更改来与控件进行接口交互


4

个人而言,我将我的控制器状态保留在 Cubit 类中。原因是因为我很可能在某个时间点使用该控制器的结果。为了保持代码的简洁性,在 Cubit 中引用控制器的文本,而不是通过事件传递文本。

另一个原因是因为你可以在 Cubit 中订阅控制器的事件(如 addListener),这被认为是“业务逻辑”。


1
听起来很合理,谢谢您的回答! - Thomas
不用谢!如果这个答案对您有帮助,请不要忘记接受它。 - mrgnhnt96
是的,但你可以使用onChanged函数来调用事件到你的bloc,并在BlocConsumer的blocListener属性中监听状态变化。 - mike-gallego

0
我建议不要在 blocs 或 cubits 中使用 TextEditingControllers,因为对我来说它是一个不应该传递到上面逻辑的 UI 级别。
如果您使用 hooks,则无论是动画还是文本控制器的问题都会消失。在 HookWidget 内部的代码如下:
final titleTextController = useTextEditingController(text: book?.title ?? '');

我可以为其添加监听器并在更改时调用一些方法,或者只获取当前文本而不关心处理,因为它会自动发生。

其他钩子包括useContext()useState()。有关钩子的更多信息,请参阅我的Flutter cubits + hooks tutorial


0
我认为将其保留在Bloc Cubit内部是一个很好的选择,因为假设您在页面上使用部分(例如:常规部分、介绍部分、表单部分)来分离小部件。想象一下,如果从父小部件向所有子小部件传递TextEditingController,那将会很麻烦。只需将其保留在cubit或bloc中,用blocbuilder包装父小部件,并可以从任何地方读取。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接