首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用getx在一个控制器中获取另一个控制器的变量

如何使用getx在一个控制器中获取另一个控制器的变量
EN

Stack Overflow用户
提问于 2021-09-05 13:04:16
回答 2查看 2.2K关注 0票数 0

这是一个与getx有关的问题。我有两个控制器。ContractsController和NotificationController.在ContractsController中,我通过调用Api请求将值放入观察者变量中。我现在想要的是在另一个控制器- NotificationController中获取该变量的数据。如何使用getx函数获得该值?

ContractsController

代码语言:javascript
运行
复制
class ContractsController extends GetxController {
  ExpiringContractRepository _expiringContractRepository;

  final expiringContracts = <ExpiringContract>[].obs; // This is the value what I want in another controller

  ContractsController() {
    _expiringContractRepository = new ExpiringContractRepository();
  }

  @override
  Future<void> onInit() async {
    await refreshContracts();
    super.onInit();
  }

  Future refreshContracts({bool showMessage}) async {
    await getExpiringContracts();
    if (showMessage == true) {
      Get.showSnackbar(Ui.SuccessSnackBar(message: "List of expiring contracts refreshed successfully".tr));
    }
  }

  Future getExpiringContracts() async {
    try {
      expiringContracts.value = await _expiringContractRepository.getAll(); // put the value from the api
    } catch (e) {
      Get.showSnackbar(Ui.ErrorSnackBar(message: e.toString()));
    }
  }
}

在api请求之后,将使用数据成功地更新expiringContracts。现在,我想在NotificationController中得到这个值

NotificationController

代码语言:javascript
运行
复制
class NotificationsController extends GetxController {
  final notifications = <Notification>[].obs;
  ContractsController contractsController;

  NotificationsController() {
  }

  @override
  void onInit() async {
    contractsController = Get.find<ContractsController>();
    print(contractsController.expiringContracts);  // This shows an empty list ?????  
    super.onInit();
  }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-05 23:44:35

在GetX中有一些强大的方法。我用Get.put和Get.find解决了这个问题

这是我添加的代码。

ContractsController

代码语言:javascript
运行
复制
class ContractsController extends GetxController {
  ExpiringContractRepository _expiringContractRepository;

  final expiringContracts = <ExpiringContract>[].obs; // This is the value what I want in another controller

  ContractsController() {
    _expiringContractRepository = new ExpiringContractRepository();
  }

  @override
  Future<void> onInit() async {
    await refreshContracts();
    super.onInit();
  }

  Future refreshContracts({bool showMessage}) async {
    await getExpiringContracts();
    if (showMessage == true) {
      Get.showSnackbar(Ui.SuccessSnackBar(message: "List of expiring contracts refreshed successfully".tr));
    }
  }

  Future getExpiringContracts() async {
    try {
      expiringContracts.value = await _expiringContractRepository.getAll(); // put the value from the API
      // ******************************** //
      Get.put(ContractsController()); // Added here
    } catch (e) {
      Get.showSnackbar(Ui.ErrorSnackBar(message: e.toString()));
    }
  }
}

NotificationController

代码语言:javascript
运行
复制
class NotificationsController extends GetxController {
  final notifications = <Notification>[].obs;
  ContractsController contractsController;

  NotificationsController() {
  }

  @override
  void onInit() async {
    // ******************************** //
    contractsController = Get.find<ContractsController>(); // Added here.
    print(contractsController.expiringContracts);  // This shows the updated value
    super.onInit();
  }
}

最后,我发现GetX是简单但强大的状态管理在颤振。谢谢。

票数 0
EN

Stack Overflow用户

发布于 2021-09-05 21:44:56

概述

我想到了几个解决方案:

  • expiringContracts列表作为构造函数参数传递给NotificationsController,如果在实例化时只需要这样做一次,或者
  • 使用GetX worker来更新NotificationsController,每次expiringContracts被更新时

第一个解决方案与GetX无关,它只是ContractsControllerNotificationsController之间的异步协调,因此让我们关注第二个解决方案: GetX工人。

详细信息

NotificationsController中,创建一个接收expiringContracts的方法。

类似于:

代码语言:javascript
运行
复制
class NotificationsController extends GetxController {

  void refreshContracts(List<ExpiringContract> contracts) {
    // do something
  }

}

请注意:所有这些代码都没有经过测试。我纯粹是用StackOverflow编写的,所以考虑一下这个伪代码。

ContractsController中,我们将以构造函数arg的形式提供上述回调方法:

ContractsController中,类似于:

代码语言:javascript
运行
复制
class ContractsController {

  final expiringContracts = <ExpiringContract>[].obs

  final Function(List<ExpiringContract>) refreshContractsCallback;

  ContractsController(this.refreshContractsCallback);

  @override
  void onInit() {
    super.onInit();
    refreshContracts();  // do your stuff after super.onInit
    ever(expiringContracts, refreshContractsCallback);
    // ↑ contracts → refreshContractsCallback(contracts)
    // when expiringContracts updates, run callback with them
  }
}

这里,GetX ever工作器将可观察的参数作为第一个参数,将一个函数作为第二个参数。该函数必须采用与观察到的变量(即List<ExpiringContract> )匹配的类型参数,因此refreshContractsCallback类型被定义为Function(List<ExpiringContract>)

现在,只要在ContractsController中更新可观察到的ContractsController,就会调用refreshContractsCallback(contracts),它通过refreshContractsNotificationsController提供过期合同的列表。

最后,当实例化两个控制器时,inside the build() method of your route/page

代码语言:javascript
运行
复制
NotificationsController nx = Get.put(NotificationsController());
ContractsController cx = Get.put(ContractsController(nx.refreshContracts));

事件时间表

  • NotificationsController是在nx.
  • nx.onInit()运行时创建的,创建了refreshContracts() starts
  • ContractsController的慢调用,而nx.refreshContracts callback
  • your页面绘制
    • nx此时没有契约数据,因此您将进行编程。需要一个FutureBuilder或一个Obx/ GetX + StatelessWidget,当数据最终恢复为GetX

nx

  • nx.refreshContracts(contracts)完成
  • 时,ever工作人员运行,将合同发送给refreshContracts()运行,并使用contracts

执行任务。

Notes

nx.onInit

  • ever完成

时,将从refreshContract工作人员中删除

  • 异步/等待
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69063658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档