GetX凭借着简单、实用的API成为Flutter最受欢迎的框架。目前已有超8k Stars,上升势头更是碾压Provider。但是在开发中,当对象的属性不是Rx的时候,直接更改会出现不生效的情况,如下 这时候我们就要调用update(void fn(T? val))进行赋值或者赋值后调用refresh()来刷新。就有了如下代码: 只有当对象的属性不是Rx,才需要用到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 { UserLogic logic = UserLogic(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ 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().obs;}class Account{ num points = 0; Rx pointsobs = 0.obs;}
分析原因:1.为什么修改对象的非Rx属性无法生效?解读:当对象的属性不是Rx的时候,对属性赋值并没有走Rxvalue的set方法。set value(T val) 通过 subject.add(value),类似往Stream里加数据。GetX是通过观察者模式实现状态管理。只有往Stream里吗添加数据,才会刷新对应数据绑定的UI。思考:要透过表面看本质,无论是refresh()、update(void fn(T? val))、还是Rxvalue的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是什么样式?- BLOC是Business Logic Component【业务逻辑模块】的缩写。是Google提出的解决UI与逻辑耦合度过高的方案。
- BLoC是使用Stream或者RxDart等工具,将数据(状态)独立出去,然后当状态有更新的时候,数据使用者自动更新
3.BLOC的实现?- BLoC数据模块,持有一个StreamController,来管理stream
- UI需要展示数据的地方,使用StreamBuilder来监听stream变化
- 当stream里的数据变化时,就会自动刷新子UI。
- 需要更新数据时,比如点击了某个按钮,则会操作BLoC数据模块,通过其StreamController更新里面的数据,这样UI就会自动刷新了。
4.GetX借鉴了什么理念? 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |