You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Flutter的showDialog中使用watch_it访问模型的视图重绘问题

解决watch_it在Flutter弹窗中无法同步模型更新的问题

核心原因

showDialog 创建的弹窗是独立于主Widget树的新上下文,默认情况下弹窗内的Widget不会自动订阅watch_it的模型变化,导致模型更新后弹窗无法重绘。

具体解决方法

方法1:在弹窗内使用 WatchItBuilder 包裹需要响应变化的Widget

直接在弹窗的Widget树中用WatchItBuilder监听目标模型,模型更新时会自动触发重绘:

showDialog(
  context: context,
  builder: (dialogContext) {
    return WatchItBuilder<YourModel>(
      builder: (context, model) {
        return AlertDialog(
          title: Text(model.someValue),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(dialogContext),
              child: const Text('关闭'),
            ),
          ],
        );
      },
    );
  },
);

替换YourModel为你的实际模型类,model.someValue为需要同步的属性即可。

方法2:在自定义弹窗Widget中手动订阅模型

如果弹窗是自定义StatefulWidget,可在生命周期中手动订阅和取消订阅:

class CustomDialog extends StatefulWidget {
  const CustomDialog({super.key});

  @override
  State<CustomDialog> createState() => _CustomDialogState();
}

class _CustomDialogState extends State<CustomDialog> {
  late YourModel _model;
  late VoidCallback _unsubscribe;

  @override
  void initState() {
    super.initState();
    _model = getIt<YourModel>();
    // 订阅模型变化,触发setState更新UI
    _unsubscribe = watchIt.watch<YourModel>((_) => setState(() {}));
  }

  @override
  void dispose() {
    _unsubscribe(); // 取消订阅,避免内存泄漏
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text(_model.someValue),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('关闭'),
        ),
      ],
    );
  }
}

使用时直接在showDialog的builder中返回这个自定义Widget即可。

方法3:使用 watch 扩展函数监听单个属性

如果只需要监听模型的某个特定属性,可用watch扩展函数简化代码:

showDialog(
  context: context,
  builder: (dialogContext) {
    final someValue = dialogContext.watch<YourModel>((m) => m.someValue);
    return AlertDialog(
      title: Text(someValue),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(dialogContext),
          child: const Text('关闭'),
        ),
      ],
    );
  },
);

该方式会自动监听指定属性的变化,属性更新时弹窗会自动重绘。

注意事项

  • 确保模型类已通过getIt.registerSingleton或类似方法注册到watch_it的依赖注入容器中。
  • 方法2需手动取消订阅,方法1和3会自动管理订阅生命周期,无需额外处理。

内容的提问来源于stack exchange,提问作者freebie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:27:06