美文网首页Flutter学习Flutter烂笔头
Flutter全局数据怎么搞? -- scoped_model

Flutter全局数据怎么搞? -- scoped_model

作者: RidingWind2023 | 来源:发表于2019-06-08 17:37 被阅读147次

scoped_model

scoped_model 能够让你很方便的传递 Model ,从 parent Widget 到它的后代。另外,当model发生变化可以,它可以重新构建所有的孩子widget。这个库是从 Fuchsia codebase提炼出来的。

该库主要提供了三个主要的类:

  • Model . 你需要继承这个这个类,来实现你自己的Models,比如 SearchModel或者UserModel。你可以监听这些model的变化。
  • ScopedModel Widget。 Model, 你可以把你的model包装进 ScopedModelWidget。这将会使Model 对所有子孙Widgets可用。
  • ScopedModelDescendantWidget。使用这个Widget可以让你在Widget树中找到更合适的ScopedModel。当 Model变化通知者通知变化时,它会自动构建。

这个仓库构建于flutter的一些特征之上:

  • Model 实现了 Listenable接口。 AnimationControllerTextEditingController也都实现了这个接口。
  • Model可以向Widget树传递 是使用了 InheritedWidget。当 InheritedWidget被重新构建时,会驱动重新构建所有依赖这个数据的Widgets。
  • 它使用了 AnimatedBuilderWidget 在底层,用来监听 Model, 当model变化时会重新构建 InheritedWidget

Examples

Counter App

用法

通过上面的 Counter样例来看看基本用法:

// Start by creating a class that holds some view the app's state. In
// our example, we'll have a simple counter that starts at 0 can be 
// incremented.
//
// Note: It must extend from Model.  
class CounterModel extends Model {
  int _counter = 0;

  int get counter => _counter;

  void increment() {
    // First, increment the counter
    _counter++;
    
    // Then notify all the listeners.
    notifyListeners();
  }
}

// Create our App, which will provide the `CounterModel` to 
// all children that require it! 
class CounterApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // First, create a `ScopedModel` widget. This will provide 
    // the `model` to the children that request it. 
    return new ScopedModel<CounterModel>(
      model: new CounterModel(),
      child: new Column(children: [
        // Create a ScopedModelDescendant. This widget will get the
        // CounterModel from the nearest ScopedModel<CounterModel>. 
        // It will hand that model to our builder method, and rebuild 
        // any time the CounterModel changes (i.e. after we 
        // `notifyListeners` in the Model). 
        new ScopedModelDescendant<CounterModel>(
          builder: (context, child, model) => new Text('${model.counter}'),
        ),
        new Text("Another widget that doesn't depend on the CounterModel")
      ])
    );
  }
}

如何查找Model

ScopedModel提供了两种方式:

  1. 使用ScopedModelDescendantWidget。 它将会找到Model 并且 会在 Model通知者通知变化时运行 builder函数。
  2. 使用ScopedModel.of静态方法。为了让这个方法更加易读和更频繁的方便访问,你可以考虑给你的Model实现你自己的of
class CounterModel extends Model {
  // ...
 
  /// Wraps [ScopedModel.of] for this [Model].
  static CounterModel of(BuildContext context) =>
      ScopedModel.of<CounterModel>(context);
}

监听多个model

很多时候我们不是使用一个巨无霸AppModel类来管理所有数据,而是会根据他们的业务逻辑进行拆分,比如 UserModelSearchModel以及
ProductModel

但是,如果你需要从两个以上model获得数据,你需要思考如何获取。有两个选择:

  1. 使用多个ScopedModelDescendantWidgets.
  2. 多次调用ScopedModel.of。无需取管理订阅关系,Flutter会通过InheritedWidgets来考虑这些。
class CombinedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final username =
      ScopedModel.of<UserModel>(context, rebuildOnChange: true).username;
    final counter =
      ScopedModel.of<CounterModel>(context, rebuildOnChange: true).counter;

    return Text('$username tapped the button $counter times');
  }
}

demo 代码也可以参见 FlutterLearnNote ScopeModel分支.
以上就是关于scoped_model的介绍,今天的烂笔头就记到这里了。


如果你觉得这篇文章对你有益,还请帮忙转发和点赞,万分感谢。

Flutter烂笔头
您的关注将是我坚持的动力源泉,再次感谢。

相关文章

网友评论

    本文标题:Flutter全局数据怎么搞? -- scoped_model

    本文链接:https://www.haomeiwen.com/subject/ywnixctx.html