Cubit中更新Model类值后如何同步更新Widget?
解决Cubit模式下点击GridView项后UI不刷新的问题
直接修改modelCategory对象的字段不会触发UI刷新,因为Cubit只有在发出新的状态时,BlocConsumer才会重新执行builder方法重建UI。你当前的操作只是修改了内存中的数据,但没有通知Cubit更新状态,所以UI不会同步变化。
以下是具体解决方案:
1. 给数据模型添加copyWith方法
Bloc/Cubit的状态应该是不可变的,需要通过复制对象来修改数据,避免直接修改原状态:
// 分类项模型 class Category { final String? categoryId; final String? categoryName; Category({this.categoryId, this.categoryName}); // 生成新对象的copyWith方法 Category copyWith({ String? categoryId, String? categoryName, }) { return Category( categoryId: categoryId ?? this.categoryId, categoryName: categoryName ?? this.categoryName, ); } } // 分类列表模型 class ModelCategory { final List<Category>? allCategories; ModelCategory({this.allCategories}); // 生成新对象的copyWith方法 ModelCategory copyWith({ List<Category>? allCategories, }) { return ModelCategory( allCategories: allCategories ?? this.allCategories, ); } }
2. 在Cubit中添加更新分类名称的方法
在CubitCategory类中新增方法,负责复制现有数据、修改指定项,然后发出新的成功状态:
class CubitCategory extends Cubit<StateResponse> { CubitCategory() : super(StateResponseInitial()); // 原有的获取分类方法 void funcCubitGetCategories() async { // ...你的API请求逻辑 } // 新增的更新分类名称方法 void updateCategoryName(int index, String newName) { // 检查当前状态是否为成功状态 if (state is StateResponseSuccess) { final currentData = (state as StateResponseSuccess).data as ModelCategory; // 复制分类列表并修改指定项 final updatedCategories = List.from(currentData.allCategories!) ..[index] = currentData.allCategories![index].copyWith( categoryName: newName, ); // 生成新的模型对象 final updatedData = currentData.copyWith(allCategories: updatedCategories); // 发出新的成功状态,通知UI更新 emit(StateResponseSuccess(data: updatedData)); } } }
3. 修改UI中的点击事件逻辑
把直接修改模型字段的代码,替换为调用Cubit的更新方法:
InkWell( onTap: (){ // 调用Cubit的更新方法,而非直接修改model cubitCategory.updateCategoryName(index, "XYz"); }, child: Container( decoration: BoxDecoration( color: Colors.black.withOpacity(.20) ), child: Column( children: [ Text("${modelCategory.allCategories![index].categoryId}"), Text("${modelCategory.allCategories![index].categoryName}"), ], ), ), ),
4. 修复API重复请求问题
你当前在BlocConsumer的bloc参数中调用funcCubitGetCategories(),会导致每次状态变化都重新请求API,需将API请求移到页面的initState中:
class YourPage extends StatefulWidget { const YourPage({super.key}); @override State<YourPage> createState() => _YourPageState(); } class _YourPageState extends State<YourPage> { final CubitCategory cubitCategory = CubitCategory(); @override void initState() { super.initState(); // 仅在页面初始化时请求一次分类数据 cubitCategory.funcCubitGetCategories(); } @override void dispose() { cubitCategory.close(); super.dispose(); } @override Widget build(BuildContext context) { return BlocConsumer<CubitCategory, StateResponse>( bloc: cubitCategory, // 此处不再调用funcCubitGetCategories() listener: (context, state) {}, builder: (context, state) { // ...你的原有builder逻辑 }, ); } }
内容的提问来源于stack exchange,提问作者Dharini Prajapati
相关产品推荐
相关产品推荐

