Flutter学习-GetX-05 生命周期

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

本文主要介绍下Getx中关于值的生命周期和状态管理的生命周期

之前介绍了关于依赖注入的2种方式,可以是直接创建或者懒加载的方式。这里关于控制器共享的情况:

Class a => Class B (has controller X) => Class C (has controller X)
复制代码

在A类中,控制器还没有进入内存,因为你还没有使用它(Get是懒加载)。在类B中,你使用了控制器,并且它进入了内存。在C类中,你使用了与B类相同的控制器,Get会将控制器B的状态与控制器C共享,同一个控制器还在内存中
如果你关闭C屏和B屏,Get会自动将控制器X从内存中移除,释放资源,因为a类没有使用该控制器。如果你再次导航到B,控制器X再次进入内存,如果你没有去C类,而是再次回到a类,Get将以同样的方式将控制器从内存中移除。 如果类C没有使用控制器,你把类B从内存中移除,就没有类在使用控制器X,同样也会被处理掉。
唯一能让Get乱了阵脚的例外情况,是如果你意外地从路由中删除了B,并试图使用C中的控制器,在这种情况下,B中的控制器的创建者ID被删除了Get被设计为从内存中删除每一个没有创建者ID的控制器。如果你打算这样做,在B类的GetBuilder中添加 "autoRemove: false "标志,并在C类的GetBuilder中使用adopID = true

1. 值的生命周期

之前介绍ObxGetX等中其中Workers是监听值的生命周期,Workers将协助你在事件发生时触发特定的回调

///每次`count1`变化时调用。
ever(count1, (_) => print("$_ has been changed"));

///只有在变量$_第一次被改变时才会被调用。
once(count1, (_) => print("$_ was changed once"));

///防DDos - 每当用户停止输入1秒时调用,例如。
debounce(count1, (_) => print("debouce$_"), time: Duration(seconds: 1));

///忽略1秒内的所有变化。
interval(count1, (_) => print("interval $_"), time: Duration(seconds: 1));
复制代码

所有worker都会返回一个Worker实例,你可以用它来取消(通过dispose())worker。

  • ever :每当 Rx 变量发出一个新的值时,就会被调用。
  • everAll :和 ever 很像,但它需要一个 Rx 值的 List,每次它的变量被改变时都会被调用。就是这样。
  • once :once只在变量第一次被改变时被调用。
  • debounce :debounce搜索函数中非常有用,你只希望API在用户完成输入时被调用。如果用户输入 "Jonny",你将在API中进行5次搜索,分别是字母J、o、n、n和y。使用Get不会发生这种情况,因为你将有一个 "debounce "Worker,它只会在输入结束时触发
  • interval :interval 与 debouce不同,debouce如果用户在1秒内对一个变量进行了1000次修改,他将在规定的计时器(默认为800毫秒)后只发送最后一次修改。Interval则会忽略规定时间内的所有用户操作。如果你发送事件1分钟,每秒1000个,那么当用户停止DDOS事件时,debounce将只发送最后一个事件。建议这样做是为了避免滥用,在用户可以快速点击某样东西并获得一些好处的功能中(想象一下,用户点击某样东西可以赚取硬币,如果他在同一分钟内点击300次,他就会有300个硬币,使用间隔,你可以设置时间范围为3秒,无论是点击300次或100万次,1分钟内他最多获得20个硬币)。debounce适用于防DDOS,适用于搜索等功能,每次改变onChange都会调用你的api进行查询。Debounce会等待用户停止输入名称,进行请求。如果在上面提到的投币场景中使用它,用户只会赢得1个硬币,因为只有当用户暂停到既定时间时,它才会被执行。

注意:Worker应该总是在启动ControllerClass时使用,所以应该总是在onInit(推荐)、Class构造函数或StatefulWidgetinitState(大多数情况下不推荐这种做法,但应该不会有任何副作用)。

class GetXHomeController extends GetxController {

  var count = 0.obs;

  add(){
    count.value++;
  }
  @override
  void onInit() {
    super.onInit();

    ever(count, (callback) => print('ever:${count.value}'));

    once(count, (callback) => print('once${count.value}'));

    debounce(count, (callback) =>  print('debounce${count.value}'),time: const Duration(seconds: 1));
  }

}
复制代码

用于一些搜索处理,或者点击频率处理。

2. contrlller的生命周期

  • GetBuilder替代StatefulWidget

在开发中我们可能会在Widget初始化的时候做些操作比如请求数据,如果是StatefulWidget则在initState中进行创建请求。或者在dispose()中调用某些方法。现在可以在GetBuilder中进行操作

GetBuilder<Controller>(
  initState: (_) => Controller.to.fetchApi(),
  dispose: (_) => Controller.to.closeStreams(),
  builder: (s) => Text('${s.username}'),
),
复制代码

但是最好还是在控制器中做相对应的操作

@override
void onInit() {
  fetchApi();
  super.onInit();
}

  ///关闭流用onClose方法,而不是dispose
  @override
  void onClose() {
    user.close();
    name.close();
    super.onClose();
  }
  
复制代码

onInit类似我们iOS中的viewDidLoadonClose则类似dealloc方法

控制器的生命周期。

  • onInit()创建控制器的地方。
  • onReady()在创建成功后马上调用
  • onClose(),关闭控制器,为删除方法做准备。
  • deleted: 你不能访问这个API,因为它实际上是将控制器从内存中删除。它真的被删除了,不留任何痕迹。

3. 小结

针对值的生命周期contrrller的生命周期我们选择在合适的时机使用对应的方法,其中如果我们想要达到页面返回是刷新,或者请求可以通过 var result = await Get.toNamed()拿到结果进行操作。

猜你喜欢

转载自juejin.im/post/7127647120374366221