是否允许从一个集团内部向另一个集团添加事件?

Is it allowed to add event to another bloc from inside of a bloc?

我正在使用 Dart 中可用的 bloc 库来实现“bloc”模式。我最终会转到 flutter_bloc 库,这样我就可以在真正的应用程序中使用它了。

我有点难以理解如何创建一些可以从更专业的集团内部调用的通用集团。我所说的专业化是指一些可能管理特定视图的集团。然后,一般集团将负责调用 API,甚至可能按顺序执行多项操作。

所以我的想法是,也许我有一个管理特定模型的 StateA,因此我使用 BlocA。每当将某个事件添加到 BlocA 时,我还需要更新由 BlocB 管理的 StateB。我不想在同一个集团内这样做,因为那些不同的州包含可能不相关的不同数据。也许我可以让 BlocC 用于应用程序的特定部分,但某些事件还应该调用 BlocABlocB.

中的事件和状态更改

我正在考虑这样写 BlocA 集团:

class BlocA extends BlocBase<BlocAEvent, BlocAState>  {
  BlocA(BlocB blocB) : super(BlocAState()) {
    _blocB = blocB;
    _blocARepository = BlocARepository();
  };

  BlocARepository _blocARepository;

  @override
  BlocAState mapEventToState(BlocAEvent event) async* {
    if (event is BlocAEventOne) {
      yield state.copyWith(valueOne: event.value);
    } else if (event is BlocAEventTwo {
      // Get data related to BlocAState
      final data = await _blocARepository.fetchImportantData()
      // ! <-- I also need to fetch additional data but that is managed
      // by different bloc - BlocB
      _blocB.add(BlocBEventOne(id: data.id));
      yield state.copyWith(dataList: SomeModel.fromJSON(data));
    }
  }
}

然后像这样创建常规 bloc BlocB

class BlocB extends BlocBase<BlocBEvent, BlocBState>  {
  BlocB() : super(BlocBState()) {
    _blocBRepository = BlocBRepository();
  };

  BlocBRepository _blocBRepository;

  @override
  BlocBState mapEventToState(BlocBEvent event) async* {
    if (event is BlocBEventOne) {
      // Get data related to BlocBState
      final data = await _blocBRepository.fetchOtherData(event.id)
      yield state.copyWith(dataList: SomeOtherModel.fromJSON(data));
    }
  }
}

我真的不确定这是否是正确的方法,因为基本上 BlocA 添加了另一个事件。但我正在尝试做一些可重用的块并使数据更加独立。我知道我也可以在 BlocA 中执行 _blocB.stream.listen 但这只会给我 BlocB 集团的状态。我需要的是对某些事件做出反应的能力。

您是否认为我的方法可能比较复杂,使用 BlocObserver 可能更合适? BlocObserver 的问题是我不确定如何在 Flutter 应用程序中正确使用它。

首先,您要实现的目标完全没问题,但让我们稍微谈谈架构。

一个选项可能是 BLoC B 订阅 BLoC A 状态变化并相应地处理。例如,这里一个更具体的 BLoC 订阅了一个更通用的 BLoC 的更改:https://github.com/felangel/bloc/blob/08200a6a03e37ce179cef10b65f34ddf6f43f936/examples/flutter_todos/lib/blocs/filtered_todos/filtered_todos_bloc.dart。为此,您需要稍微调整 BLoC A 状态(以便您可以识别这个特定的 change/event),这可能不是一个可行的方法。

您应该考虑的另一件事是您是否要紧密耦合 BLoC(在您的示例中,BLoC B 引用通过构造函数传递给 BLoC A)。为此,您可以创建某种在内部使用流的中介 class:BLoC A 可以向该中介 class 接收器发布一个事件,所有订阅者都将通过公开的流接收它(在您的情况下 - BLoC B 应该订阅那个流)——所以那里的通信就像 BLoC A -> Mediator -> BLoC B。这基本上就是 Mediator/Observer OOP 设计模式解决的问题。这样做的好处是您的 BLoC 不会相互了解,多个 BLoC 可以订阅多个不同的事件流,这意味着您可以随时向您的事件添加更多订阅者 (BLoC)。

您可以在您的事件中定义回调并在您的集团中调用它,如下所示:

    blocA.add(BlocAEvent(whenDone: () {
      blocB.add(BlocBEvent())
    }));