从Provider迁移至GetX时无法通过Get.find定位正确Controller
问题原因
- GetX 中同类型的控制器实例依靠类型+唯一tag做唯一标识,你当前初始化两个
Table控制器时没有传入区分用的tag,GetX会默认将其识别为同一个控制器实例,Get.find<Table>()默认也只会返回最后一次初始化的无tag实例。 - 无参数调用
update()时,会触发当前控制器绑定的所有无id标识的GetBuilder重建,你没有给两个GetBuilder设置区分标识,导致任意控制器触发更新都会同时刷新两个桌台的UI。
解决方案
只需给每个GetBuilder设置和桌台对应的唯一tag参数即可,修改后的代码如下:
界面部分代码
Widget build(BuildContext context) { return MaterialApp( title: 'Restaurant', home: Column( children: [ GetBuilder<Table>( tag: "Staff", // 新增唯一tag,和桌台对应 init: Table("Staff"), builder: (Table t) { return Column(children: [ Text("Staff seated: ${t.seated}"), ElevatedButton( child: const Text("Seat Staff"), onPressed: () { // 两种调用方式二选一即可 // 方式1:直接使用builder传入的控制器实例 t.toggleSeated(); // 方式2:通过tag查找对应实例 // Get.find<Table>(tag: "Staff").toggleSeated(); }, ), ]); }, ), GetBuilder<Table>( tag: "VIP", // 新增唯一tag,和桌台对应 init: Table("VIP"), builder: (Table t) { return Column(children: [ Text("VIP seated: ${t.seated}"), ElevatedButton( child: const Text("Seat VIP"), onPressed: () { t.toggleSeated(); // Get.find<Table>(tag: "VIP").toggleSeated(); }, ), ]); }, ), ], )); }
控制器代码无需修改
class Table extends GetxController { final String name; int chairs = 0; bool seated = false; Table(this.name); toggleSeated() { seated = !seated; update(); } }
如果后续有动态生成的桌台需求,直接将桌台的唯一ID/名称作为tag参数传入即可实现多实例独立控制。
内容的提问来源于stack exchange,提问作者Kernel James
相关产品推荐
相关产品推荐

