美文网首页
GetX在什么情况下update、或refresh方法?

GetX在什么情况下update、或refresh方法?

作者: Hamiltonian | 来源:发表于2022-03-02 15:01 被阅读0次

    GetX凭借着简单、实用的API成为Flutter最受欢迎的框架。目前已有超8k Stars,上升势头更是碾压Provider。

    但是在开发中,当对象的属性不是Rx<T>的时候,直接更改会出现不生效的情况,如下
    这时候我们就要调用update(void fn(T? val))进行赋值或者赋值后调用refresh()来刷新。就有了如下代码:

    只有当对象的属性不是Rx<T>,才需要用到update、或refresh方法。在别的情况都不必要调用此方法!

    ///pointsobs的值会改变
              logic.account.value.pointsobs.value =
                  logic.account.value.pointsobs.value + 1;
              ///界面points的值不会改变
              logic.account.value.points = logic.account.value.points+1;
              ///要刷新points,还有调用这行代码
              // logic.account.refresh();
    
              /// 或者直接调用update方法
              // logic.account.update((val) {
              //   val!.points = val.points + 1;
              // });
    

    完整的示例代码

    class _MyHomePageState extends State<MyHomePage> {
      UserLogic logic = UserLogic();
    
      @override
      Widget build(BuildContext context) {
    
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Obx(() {
                  return Text(
                    'points:${logic.account.value.points}',
                    style: Theme.of(context).textTheme.headline4,
                  );
                }),
                Obx(() {
                  return Text(
                    'pointsobs:${logic.account.value.pointsobs.value}',
                    style: Theme.of(context).textTheme.headline4,
                  );
                }),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              ///pointsobs的值会改变
              logic.account.value.pointsobs.value =
                  logic.account.value.pointsobs.value + 1;
              ///界面points的值不会改变
              logic.account.value.points = logic.account.value.points+1;
              ///要刷新points,还有调用这行代码
              // logic.account.refresh();
    
              /// 或者直接调用update方法
              // logic.account.update((val) {
              //   val!.points = val.points + 1;
              // });
            },
            child: const Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
    
    
    
    class UserLogic extends GetxController{
      Rx<Account> account = Account().obs;
    }
    
    class Account{
      num points = 0;
      Rx<num> pointsobs = 0.obs;
    }
    

    分析原因:

    1.为什么修改对象的非Rx<T>属性无法生效?

    解读:当对象的属性不是Rx<T>的时候,对属性赋值并没有走Rx<T>value的set方法。set value(T val) 通过 subject.add(value),类似往Stream里加数据。GetX是通过观察者模式实现状态管理。只有往Stream里吗添加数据,才会刷新对应数据绑定的UI。

    思考:要透过表面看本质,无论是refresh()、update(void fn(T? val))、还是Rx<T>value的set方法,之所以能刷新数据是因为往Stream里面发射数据!

      void refresh() {
        subject.add(value);
      }
    
     void update(void fn(T? val)) {
        fn(_value);
        subject.add(_value);
      }
    
      set value(T val) {
        if (subject.isClosed) return;
        sentToStream = false;
        if (_value == val && !firstRebuild) return;
        firstRebuild = false;
        _value = val;
        sentToStream = true;
        subject.add(_value);
      }
    

    2.GetX遵循的BLOC是什么样式?

    1.png
    • BLOC是Business Logic Component【业务逻辑模块】的缩写。是Google提出的解决UI与逻辑耦合度过高的方案。
    • BLoC是使用Stream或者RxDart等工具,将数据(状态)独立出去,然后当状态有更新的时候,数据使用者自动更新

    3.BLOC的实现?

    2.png
    • BLoC数据模块,持有一个StreamController,来管理stream
    • UI需要展示数据的地方,使用StreamBuilder来监听stream变化
    • 当stream里的数据变化时,就会自动刷新子UI。
    • 需要更新数据时,比如点击了某个按钮,则会操作BLoC数据模块,通过其StreamController更新里面的数据,这样UI就会自动刷新了。

    4.GetX借鉴了什么理念?

    • 观察者模式【对Stream流的监听】
    • 生产者消费者 【Logic状态类就像饭堂,UI界面是消费着】


      3.png

    相关文章

      网友评论

          本文标题:GetX在什么情况下update、或refresh方法?

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