ChangeNotifier 安装等效?

Posted

技术标签:

【中文标题】ChangeNotifier 安装等效?【英文标题】:ChangeNotifier mounted equivalent? 【发布时间】:2020-02-22 11:47:00 【问题描述】:

我正在使用 ChangeNotifier 从 Stateful Widget 中提取一些逻辑到 Provider:class Model extends ChangeNotifier ...

在我的有状态小部件中,我有:

  if (mounted) 
setState(() );

如何检查 Widget 是否安装在模型中?

例如我如何调用:

 if (mounted) 
notifyListeners();

【问题讨论】:

【参考方案1】:

一种简单的方法是将 Stateful Widget 的“State”作为参数传递给“Model”。

像这样:

class Model extends ChangeNotifier 

  Model(this.yourState);

  YourState yourState;

  bool get _isMounted => yourState.mounted;


class YourState extends State<YourStatefulWidget> 
  Model model;

  @override
  void initState() 
    super.initState();
    model = Model(this);
  

  @override
  Widget build(BuildContext context) 
    // your code..
  


我认为您不需要检查State 是否已安装。您只需要检查模型是否已被处理。你可以覆盖ChangeNotifier中的dispose()方法:

class Model extends ChangeNotifier 
  bool _isDisposed = false;

  void run() async 
    await Future.delayed(Duration(seconds: 10));
    if (!_isDisposed) 
      notifyListeners();
      
  

  @override
  void dispose() 
    super.dispose();
    _isDisposed = true;
  

并且不要忘记在处理State 时处理Model

class YourState extends State 
  Model model;

  @override
  void initState() 
    super.initState();
    model = Model();
  

  @override
  void dispose() 
    model?.dispose();
    super.dispose();
  
  /// Your build code...


或者你可以在Provider包中使用ChangeNotifierProvider,它会帮助你自动处理Model

class YourState extends State 
  Model model;

  @override
  void initState() 
    super.initState();
    model = Model();
  

  @override
  Widget build(BuildContext context) 
    return ChangeNotifierProvider<Model>(
      builder: (build) => model,
      child: Container(
        child: Consumer<Model>(
          builder: (context, model, widget) => Text("$model"),
        ),
      ),
    );
  


【讨论】:

谢谢,我在使用 TabController 并从选项卡 1 切换到选项卡 3 时遇到了类似的问题。执行此操作时,选项卡 2 也已初始化,调用 notifyListeners() 导致异常,因为小部件已被释放。 尝试检查 ChangeNotify 已处置而不是已安装状态。我已经为你编辑了答案。 @anka【参考方案2】:

只要你用提供者模型状态包装你的小部件 众所周知,一旦您的小部件被处置 默认情况下,包装它的提供者模型已经被释放

所以你所要做的就是定义一个变量 isDisposed 并修改 notifyListeners 如下

MyState with ChangeNotifier

// to indicate whether the state provider is disposed or not
 bool _isDisposed = false;


   // use the notifyListeners as below
   customNotifyListeners()
    if(!_isDisposed)
       notifyListeners()
    
   




 @override
  void dispose() 
    super.dispose();
    _isDisposed = true;
  


【讨论】:

以上是关于ChangeNotifier 安装等效?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ChangeNotifier 导航?

Flutter 数据监听器ChangeNotifier

实施 ChangeNotifier 与 StateNotifier

为大量听众优化的 ChangeNotifier 的替代方案?

如何关闭 ChangeNotifier Provider Flutter 中的函数

如何在 ChangeNotifier 中使用 Futures?