美文网首页
Flutter-状态管理(scoped_model)

Flutter-状态管理(scoped_model)

作者: coolzpw | 来源:发表于2019-04-03 10:52 被阅读0次

    Flutter是一款响应式的UI框架,其中设计灵感很多来源于React.同React一样,它将数据与视图分离,由数据作为驱动去映射渲染视图.so,也将widget分为Stateless widgetsStateful widgets

    • StatelessWidget: 是不可变的, 它是无状态的,这意味着这些控件的属性不能改变,是静态的,就是我们常说的写死的页面.
    • StatefulWidget: 持有的状态,是动态页面.它会随状态的改变而重新渲染自己本身.(StatefulWidget类本身是不变的,起作用的是State类,它在widget生命周期中始终存在的.)

    实现一个有状态的页面如下:

    // 1.继承StatefulWidget,并实现其createState()方法,与自己的state绑定.
    class HomePage extends StatefulWidget {
    @override
    _HomePageState createState() {
      return new _HomePageState();
    }
    }
    
    //2继续State,并实现其build()方法创建自己UI视图,通过调用setState方法去触发视图的渲染更新
    class _HomePageState extends State<HomePage>{
      @override
      void initState() {
          super.initState();
    }
    
      @override
    Widget build(BuildContext context) {
      return SingleChildScrollView(
        child: Column(
          children: ContentLayout(),
        ),
      )
    }
    }
    

    实现一个拥有状态的页面至少需要实现其两个类.你可能会意识到,随着功能的增加,页面的累积,会出现越来越多的状态页面,而且还会有多个页面共享同一个状态,导致代码抒写过于冗余和复杂.这时候,基于迫切的需要,状态管理框架应运而生。

    scoped_model
    用于管理状态的框架.官方文档介绍中写道,它可以轻松将数据模型从父级widget传入它的children,并且当数据模型发生改变时,会自发的更新所有使用她的wigdet.现在来简单讲解下它的用法.

    这里有三个主要用到的类:

    • Model 如名,定义数据的类,将你要数据定义在一个类并继承于它,类中有个notifyListeners(),用于刷新与它关联的widgets.
    import 'package:scoped_model/scoped_model.dart';
    
    class CounterModel extends Model {
      int _counter = 0;
    
      int get counter => _counter;
    
      void increment() {
        // First, increment the counter
        _counter++;
    
        // Then notify all the listeners.
        notifyListeners();
      }
    }
    
    • ScopedModel 它其实是个widget,继承于StatelessWidget类.它主要接收两个参数:model(数据模型)和child(会使用到这个数据模型对应的widget).

    • ScopedModelDescendant 它也继承于StatelessWidget,使用此widget,其包含的子wigets可以找到对应的ScopedModel,它可以获取与ScopedModel绑定的数据模型,且当数据模型发送改变时,它将自动重新构建渲染.说白了,它主要功能就是让子页面能够获取到model即数据~

    class CounterApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        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:

    final countModel = ScopedModel.of<CountModel>(context);
    

    然后这里我也有个比较疑惑的地方,就是当一个widet需要使用多个Model时,参考官方文档讲解(https://pub.dartlang.org/packages/scoped_model):

      1. Use multiple ScopedModelDescendant Widgets
      1. Use multiple ScopedModel.of calls. No need to manage subscriptions, Flutter takes care of all of that through the magic of 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');
      }
    }
    

    当是我在看ScopedModel 和ScopedModelDescendant 源码时,类中并有提供接受多个model的构造方法. 然后参考https://juejin.im/post/5b97fa0d5188255c5546dcf8 , 是指Model 使用使用Mixin进行多继承,但这必定带来很多耦合

    (如果有说的不当的,也请大佬赐教~共同交流,共同进步!)

    相关文章

      网友评论

          本文标题:Flutter-状态管理(scoped_model)

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