如果ChangeNotifier通过提供者程序包(类似于BlocListener)进行通知,该如何“做什么”?

时间:2019-12-18 21:42:52

标签: flutter dart flutter-provider

我想要的

我有一个简单的模型。该模型从ChangeNotifier扩展。如果ChangeNotifier调用notifyListeners(),我想“做”一些类似显示SnackBar或Dialog的操作。我为模型提供了Provider包到我的小部件树。

它与什么具有可比性?

我以前使用过flutter_bloc软件包。该软件包提供了BlocListener。使用BlocListener,我可以在状态更改时“执行”操作。示例代码:

BlocListener<BlocA, BlocAState>(
  listener: (context, state) {
    // do stuff here based on BlocA's state
  },
  child: Container(),
)

在上面的示例中,孩子不会重建,但是我仍然可以根据状态做一些事情。

有什么可与提供程序包相提并论的吗?我在该软件包的文档中读到,ListenableProvider将给予更大的自由来执行诸如“动画”之类的工作。但是我不知道是否可以通过某种方式使用此提供程序在通知上显示小吃店。

编辑:我在Twitter上问了Provider的作者Remi。他只告诉我几个字符,我可以使用didChangeDependencies来实现此行为。

1 个答案:

答案 0 :(得分:1)

为此请谨慎使用didChangeDependencies。在少数情况下,didChangeDepdnencies可以用于此目的,而https://github.com/flutter/flutter/pull/49527将使其无法使用。

基本问题是didChangeDepdnencies有时(或总是在#49527之后)在树被锁定以防止状态改变的时候被调用。在请求请求之前,仅在以下情况下安全:

  • 不是第一次(在构建范围内调用)
  • 不是取消激活元素并最终将其卸载的时间,因此不再位于树中的有效位置(此调用在pull请求之后将不再发生)。

更安全的方法是:

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  if (Provider.of(context).whatever == someCondition) {
    SchedulerBinding.instance.addPostFrameCallback(() {
      // show modal or dialog
    });
  }
}

使用此代码更安全,因为可以保证在树中状态可以安全更改的点上运行,而不是仅在某些非常特殊的情况下运行而无需帧回调。

可能有比这更优雅的解决方案(例如,直接在您的ChangeNotifier的notifyListeners上添加回调,假设它仅在树处于可变状态时才触发)。