Checkbox UI未更新,尽管复选框的项目值已更新,GetX颤动
获取工作代码示例”此处
我有一个rxlist
addonProducts
,其中包含product
和selected
属性。
我正在尝试实现简单的多选择网格视图,但是在单击复选框时,所选属性更改,但不会反射回UI, 如果我刷新它将更新。
我尝试了obx()=> ();小部件,它仍然没有更新
我的产品控制器
class ProductsController extends GetxController {
late Worker worker;
static ProductsController instance = Get.find();
RxList<ProductModel> products = RxList<ProductModel>([]);
RxList<CheckProduct> addOnProducts = <CheckProduct>[].obs;
String collection = "products";
@override
void onReady() {
super.onReady();
products.bindStream(getAllProducts());
worker = once(products, (List<ProductModel> value) {
fillAddOnProducts(value);
}, condition: () => products.isNotEmpty);
}
Stream<List<ProductModel>> getAllProducts() => FirebaseFirestore.instance
.collection(collection)
.snapshots()
.map((query) => query.docs
.map((item) => ProductModel.fromMap(item.data(), item.id))
.toList());
void fillAddOnProducts(List<ProductModel> products) => {
products.forEach((element) {
addOnProducts.add(CheckProduct(product: element, selected: false));
})
};
}
class CheckProduct {
ProductModel product;
bool selected;
CheckProduct(
{required ProductModel this.product, required bool this.selected});
}
我的网格视图
class AddOns extends StatelessWidget {
const AddOns({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [],
title: Text("Select Addons"),
),
body: Obx(() => GridView.count(
crossAxisCount: 2,
children: productsController.addOnProducts
.map((element) => ProductWidget(product: element))
.toList(),
)));
}
}
class ProductWidget extends StatelessWidget {
final CheckProduct product;
const ProductWidget({Key? key, required this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
margin: EdgeInsets.all(10),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
top: 4,
left: 4,
child: Checkbox(
value: product.selected,
onChanged: (value) {
print("value of the value is : $value");
print("value of product selected before is: " +
product.selected.toString());
product.selected = value!;
print("value of product selected after is: " +
product.selected.toString());
},
),
),
],
));
}
}
,因此在控制台中是:
I/flutter (20067): value of the value is : true
I/flutter (20067): value of product selected before is: false
I/flutter (20067): value of product selected after is: true
但是复选框没有更新,仅在刷新时才更新,如何克服它?将obx()添加到父母无济于事。
在下面的代码这里这只是问题和问题所面临的。
Get the working code sample here
I have an RxList
of addOnProducts
which contains product
and selected
attributes.
I am trying to implement the simple multiSelectable grid View, but on clicking the checkBox the selected attribute changes but it is not reflected back to the ui,
If i refresh it will be updated.
I tried Obx()=> (); widget , It is still not updating
My ProductController
class ProductsController extends GetxController {
late Worker worker;
static ProductsController instance = Get.find();
RxList<ProductModel> products = RxList<ProductModel>([]);
RxList<CheckProduct> addOnProducts = <CheckProduct>[].obs;
String collection = "products";
@override
void onReady() {
super.onReady();
products.bindStream(getAllProducts());
worker = once(products, (List<ProductModel> value) {
fillAddOnProducts(value);
}, condition: () => products.isNotEmpty);
}
Stream<List<ProductModel>> getAllProducts() => FirebaseFirestore.instance
.collection(collection)
.snapshots()
.map((query) => query.docs
.map((item) => ProductModel.fromMap(item.data(), item.id))
.toList());
void fillAddOnProducts(List<ProductModel> products) => {
products.forEach((element) {
addOnProducts.add(CheckProduct(product: element, selected: false));
})
};
}
class CheckProduct {
ProductModel product;
bool selected;
CheckProduct(
{required ProductModel this.product, required bool this.selected});
}
My Grid View
class AddOns extends StatelessWidget {
const AddOns({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [],
title: Text("Select Addons"),
),
body: Obx(() => GridView.count(
crossAxisCount: 2,
children: productsController.addOnProducts
.map((element) => ProductWidget(product: element))
.toList(),
)));
}
}
class ProductWidget extends StatelessWidget {
final CheckProduct product;
const ProductWidget({Key? key, required this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
margin: EdgeInsets.all(10),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
top: 4,
left: 4,
child: Checkbox(
value: product.selected,
onChanged: (value) {
print("value of the value is : $value");
print("value of product selected before is: " +
product.selected.toString());
product.selected = value!;
print("value of product selected after is: " +
product.selected.toString());
},
),
),
],
));
}
}
Therefore in the console it is :
I/flutter (20067): value of the value is : true
I/flutter (20067): value of product selected before is: false
I/flutter (20067): value of product selected after is: true
But the checkBox is not updating, it updates only when i refresh, How to overCome this? Adding Obx() to the parent isn't helping..
Find the github link to code below here which has just the question and and the problem faced..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
经过代码后。我已经实施了以下以下情况,它将在没有热重加载的情况下改变状态:
在您的主要飞镖中,您不需要将产品控制器放在这里,因为您不使用它
main.dart
接下来,我已经更改了您的网格类以生成产品窗口小部件的列表,作为AddProduct List长度的大小。在我看来,这是一种写格里视图的更好方法。从您的GridView中删除OBX,并在使用GETX时将您的状态小部件更改为无状态的小部件。即使在无状态的小部件中,它也会管理您的状态。在此处添加您的产品控制器,因为您将从控制器类访问AddProduct List。
grid.dart
在您的产品控制器类中,删除实例,因为这并不重要。这是这里唯一的变化:
productController.dart
最后,您的ProductWidget类需要所需的值索引。因此,小部件知道GridView中的哪个索引用户在此处单击并在复选框中使用OBX(),因为您在此处选择了可观察的值。请记住,当您具有obs值时,请始终使用obx()。每当obs值更改时,这都会更新小部件。在这里,如果您注意到我们使用的是get.find()而不是put作为get.put已在范围内部,因此您需要做的就是找到要使用的控制器。您可以根据需要找到或放置多个控制器并尽可能多地更新值。
productwidget.dart
浏览getx文档,以适当使用getx。即使我在PlayStore中使用GetX有2个应用程序,但我仍然会不时浏览文档。他们有关于如何管理状态的明确文件。
After going through your code. I've implemented the following that will change state without hot reload:
In your main dart you do not need to put your product controller here as you are not using it
main.dart
Next, I have changed your grid class to generate a list of product widget as the size of the addProduct list length. In my opinion this is a better way to write GridView counts children. Remove obx from your gridview and change your stateful widget to stateless as you are using Getx. It will manage your state even in a stateless widget. Add your product controller here as you will access addProduct list from the controller class.
grid.dart
In your product controller class, remove the instance as it is not important. That is the only change here:
ProductController.dart
Lastly, your productWidget class needs a required value index. So, the widget knows which index in gridview the user is clicking and use Obx() here in checkbox as you have an observable value selected here. Remember to always use Obx() when you have an obs value. This will update the widget whenever an obs value changes. Here, if you notice we are using Get.find() instead of Put as Get.put is already inside the scope so all you need to do is find the controller that you will use. You can find or put multiple controllers and update values as much as you want.
productWidget.dart
Go through GetX documentation for proper use of GetX. Even though I have 2 apps in Playstore with GetX, I still go through documentation from time to time. They have a clear documentation on how to manage state.
在productwidget中添加一个额外的obx()解决了我的问题
In ProductWidget adding an additional Obx() solved my problem