从服务刷新多个视图模型 class

Refreshing multiple view models from a service class

上下文

我的项目是这样的:

+-- screens
|   +-- main_screen.dart
|   +-- details_screen.dart
|   +-- summary_screen.dart
+-- viewmodels
|   +-- main_screen_viewmodel.dart
|   +-- details_screen_viewmodel.dart
|   +-- summary_screen_viewmodel.dart
+-- services
|   +-- caching.dart
|   +-- api.dart
+-- lib.dart

屏幕使用包含所有所需数据的 ViewModel;对模型的任何更改都会导致重建视图:

// main_screen.dart
class _MainScreenState extends State<MainScreen> {
  final model = MainScreenViewModel();

  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MainScreenViewModel>(
      create: (BuildContext context) => widget.model,
      child: Consumer<MainScreenViewModel>(
        builder: (context, model, child) => Text(model.welcomeMessage)
      )
    );
  }
}

这一切看起来都像是一个相当标准的 Provider 实现;是时候描述我的问题了。

问题

我有一个名为 Caching 的 class 来处理 API 请求的缓存。当对资源(例如事务)进行更改时,我想触发我所有视图模型的刷新,以便 UI 显示更新的数据。

如何从我的缓存中访问 ViewModels class 以触发更新?

我曾经使用 StreamController 来处理这个问题,例如:
在我的视图模型中,我有这部分代码,这一行为 Stream _basketService.historiesStreamNotifier.listen((value) async {await fetchData();});

创建监听器

在服务内部声明我的 StreamController :

StreamController<int> _historiesStreamControllerNotifier =
      StreamController<int>.broadcast();

Stream<int> get historiesStreamNotifier =>
      _historiesStreamControllerNotifier.stream;

所以每当我需要从我的服务中刷新我的视图模型时,我只需调用 _historiesStreamControllerNotifier.sink.add(0); 这将触发用 .listen(...)

定义的回调

在您必须更新的服务上,例如服务 A 和服务 B 添加这个

final StreamController<int> _dataStreamController = StreamController<int>.broadcast();
    
Stream<int> get dataStream => _dataStreamController.stream;

在您的 BASE 模型上,添加一个 listen() 方法,这样所有视图模型都可以访问它

  void listen() {
    final aService = locator<ServiceA>();
    final bService = locator<ServiceB>();

    aService.dataStream.listen((_) async {
      notifyListeners();
    });
    bService.dataStream.listen((_) async {
      notifyListeners();
    });
  }

正在观看

   BaseView<BViewModel>(
                          onModelReady: (viewModel) {
                          viewModel.listen();
                        },builder: (context, viewModel, child) {
                          return AlignedGridView.count( ...

再次在服务上,一旦您更新了服务上的某些内容并且您想要通知所有监听视图模型该更改

... some successful api request ...
      _dataStreamController.sink.add(0);