Flutter-状态管理(scoped_model)

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{
  @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(
        model: new CounterModel(),
        child: new Column(children: [
          // Create a ScopedModelDescendant. This widget will get the
          // CounterModel from the nearest ScopedModel.
          // 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(
            builder: (context, child, model) => new Text('${model.counter}'),
          ),
          new Text("Another widget that doesn't depend on the CounterModel")
        ])
    );
  }
}

当然还有另一种方法获取到Model:

final countModel = ScopedModel.of(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(context, rebuildOnChange: true).username;
    final counter =
      ScopedModel.of(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))