为了学习 GetX,我创建了一个简单的控制器类:
class MyDataController extends GetxController {
RxString aString = ''.obs;
void updateString(String s) {
aString.value = s;
}
}
aString
的值显示在两个类中:AppBar
(此处未讨论)和另一个设置并显示 aString
的类:
class Level1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
final MyDataController controller = Get.find();
final textController = TextEditingController();
return Column(
children: [
TextField(
controller: textController,
onChanged: (_) {
controller.updateString(textController.text);
},
),
Text(controller.aString.value),
],
);
}
}
我不知道哪些小部件需要包含在 Obx()
的实例中。
如果我只将 Text()
(显示小部件)包装在 Obx
实例中,它会在 TextField()
(输入小部件)更改时更新。如果我只将 TextField()
小部件包装在一个 Obx
实例中,我会收到一条错误消息:
构建 Obx(has builder,dirty, 状态:_ObxState#019a0): [Get] 已检测到 GetX 的不当使用。 您应该只对将更新的特定小部件使用 GetX 或 Obx。 如果您看到此错误,您可能没有在 GetX/Obx 中插入任何可观察变量 或将它们插入 GetX 认为适合更新的范围之外 (例如:GetX => HeavyWidget => variableObservable)。 如果您需要更新父小部件和子小部件,请将每个小部件包装在 Obx/GetX 中。
一切似乎都很清楚:显示状态的小部件必须包含在 Obx()
实例中才能显示更新的变量。这是完全有道理的。更改状态的小部件不需要包装在 Obx()
实例中。
不过,我很困惑,因为如果我将两个小部件包装在单独的 Obx()
实例中,我会收到错误消息。但是,如果我将整个 Column()
包装在一个 Obx()
实例中,则当 TextField()
更改时,文本会正确更新。 ...我的理解中缺少什么?
答案 0 :(得分:3)
当您将 Text 小部件包装在 Obx 中时,您已经掌握了所有内容。实际上,最好仅包装需要在 Obx 中更新的最小小部件,在本例中为 Text
小部件。
让我解释一下您尝试测试的情况:
案例 1:当您仅将 Text
小部件包装在 Obx 中时(最好的做法)
这个案例恰好是最好和最受鼓励的方法。在这种情况下,当控制器 (MyDataController) 中 aString 的值发生变化时,Obx 会被通知从头开始仅重新构建受影响的 Text
小部件,并且这正是 GetX 的目标。
案例 2:当您将 Text
&& 和 TextField
小部件同时包装在 Obx 中时(这会引发错误)。
在本例中,您已将 Text
和 TextField
小部件都封装在 Obx 中,因此我们可以让 case 1 说明 Text
小部件。
现在,转到 TextField
小部件,会发生错误,因为 TexField
小部件不以任何方式依赖于任何 obs-value(可观察值)。
请务必注意,在提供给 textField 的 onChanged 回调中,在 updateString
上调用的方法 controller
对 TextField 的参数没有任何影响,因此这会导致 GetX 抛出错误,因为您正在尝试强制更新/重建一个不需要重建的小部件。
案例 3:当您将整列包裹在 Obx 中时(不会抛出错误,但不是最佳实践)。
在这种情况下,小部件的构建不会有任何错误,因为 Text
小部件(位于列内)依赖于 aString
的值。因此,让我们看看调用 updateString
方法时会发生什么。
当 updateString
被调用时,整个 Column 被重建(连同 TextField
和 Text
小部件,这个动作也会导致值在要更新的 Text
小部件。
现在,您可以理解为什么这第三种情况可能是有害的,如果您尝试将整个应用程序包装在 Obx 中,那么您的整个应用程序将不得不重新构建(这确实会对您的应用程序的性能产生负面影响。当然 GetX 有办法不允许这样做,因此当您尝试在 Obx 或 GetX 中包装 HeavyWidget 时会引发错误。