Flutter中使用GetX如何在一个控制器内获取另一个控制器的变量
问题根因
ContractsController 的 onInit 方法是异步执行的,API请求属于耗时操作,在NotificationsController执行onInit取数时,ContractsController的API请求还未完成,expiringContracts还处于初始空列表状态,所以打印为空。同时直接读取一次变量值的方式,也无法监听到后续API返回后的变量更新。
解决方案
方案1:使用GetX Worker监听响应式变量更新(最推荐)
GetX内置的Worker机制可以监听响应式变量的变化,只要变量更新就会触发回调,不用关心API请求的时机:
class NotificationsController extends GetxController { final notifications = <Notification>[].obs; ContractsController contractsController; NotificationsController(); @override void onInit() async { contractsController = Get.find<ContractsController>(); // 永久监听expiringContracts的变化,每次更新都会触发回调 ever(contractsController.expiringContracts, (List<ExpiringContract> newValue) { print("拿到更新后的到期合同数据:$newValue"); // 此处执行你的业务逻辑,比如生成通知、更新notifications列表等 }); super.onInit(); } }
补充说明:如果只需要监听第一次变量更新,可以把ever换成once;如果需要防抖处理(比如变量频繁更新只取最后一次),可以用debounce。
方案2:等待ContractsController初始化完成再取值
如果你的业务逻辑必须拿到合同数据才能继续执行,可以在依赖注入时等待ContractsController的初始化请求完成:
依赖注入阶段代码示例:
// 注册ContractsController时等待异步初始化完成 await Get.putAsync<ContractsController>(() async { final controller = ContractsController(); await controller.refreshContracts(); return controller; }); // 再注册NotificationsController Get.put(NotificationsController());
这种场景下你在NotificationsController的onInit里直接读取contractsController.expiringContracts.value就可以直接拿到非空的返回数据。
方案3:UI层直接使用响应式变量
如果需要在Widget中展示该变量的数据,直接用Obx包裹即可自动响应更新,无需额外在控制器中处理:
Obx(() { final contracts = Get.find<ContractsController>().expiringContracts; return ListView.builder( itemCount: contracts.length, itemBuilder: (context, index) => Text(contracts[index].name), ); })
内容的提问来源于stack exchange,提问作者Speeder
相关产品推荐
相关产品推荐

