Flutter中如何将ProductsModel转换为LocalProductsModel存入Hive
解决ProductsModel到LocalProductsModel的转换问题
你遇到的核心问题是:ProductsModel和LocalProductsModel是两个完全独立的Dart类,不能直接用cast强制转换,必须手动实现两者之间的字段映射逻辑。下面是一步步的解决方法:
1. 给Local模型添加转换构造函数
我们需要在每个Local模型中添加一个从对应原模型转换的构造方法,把原模型的字段值逐个映射到Local模型中。
1.1 给LocalCategoriesModel添加转换构造
class LocalCategoriesModel { // 保留原有代码... // 添加从CategoriesModel转换的构造 factory LocalCategoriesModel.fromCategoriesModel(CategoriesModel model) { return LocalCategoriesModel( id: model.id, name: model.name, ); } }
1.2 给LocalImagesModel添加转换构造
class LocalImagesModel{ // 保留原有代码... // 添加从ImagesModel转换的构造 factory LocalImagesModel.fromImagesModel(ImagesModel model) { return LocalImagesModel( id: model.id, src: model.src, name: model.name, ); } }
1.3 给LocalProductsModel添加转换构造
这个构造需要处理列表类型的字段(categories和images),逐个转换列表中的元素:
@HiveType(typeId: 0) class LocalProductsModel { // 保留原有代码... // 添加从ProductsModel转换的构造 factory LocalProductsModel.fromProductsModel(ProductsModel model) { // 转换分类列表:把每个CategoriesModel转成LocalCategoriesModel final localCategories = model.categories?.map((cat) => LocalCategoriesModel.fromCategoriesModel(cat))?.toList() ?? []; // 转换图片列表:把每个ImagesModel转成LocalImagesModel final localImages = model.images?.map((img) => LocalImagesModel.fromImagesModel(img))?.toList() ?? []; return LocalProductsModel( id: model.id, name: model.name, catalog_visibility: model.catalog_visibility, description: model.description, short_description: model.short_description, price: model.price, regular_price: model.regular_price, sale_price: model.sale_price, date_created: model.date_created, categories: localCategories, images: localImages, ); } }
2. 修复Hive存储逻辑
你之前存的是ProductsModel转成的Map,现在我们直接转换为LocalProductsModel实例再存入Hive(Hive会自动处理序列化):
postCartLocal(ProductsModel products){ // 先把ProductsModel转换为LocalProductsModel final localProduct = LocalProductsModel.fromProductsModel(products); // 直接存入Hive,无需手动转Map Hive.box('cart').add(localProduct); }
3. 修复Hive读取逻辑
现在Hive中存储的是LocalProductsModel实例,读取时可以直接获取,不需要错误的类型转换:
Widget _buildListView(){ return ValueListenableBuilder( valueListenable: Hive.box('cart').listenable(), builder: (context, Box cartBox, widget){ return ListView.builder( itemCount: cartBox.length, itemBuilder: (context, index) { // 直接获取LocalProductsModel实例 final cartItem = cartBox.getAt(index) as LocalProductsModel; print('商品名称:${cartItem.name}'); // 记得返回实际的列表项Widget,比如ListTile return ListTile( title: Text(cartItem.name), subtitle: Text(cartItem.price ?? cartItem.regular_price), ); }, ); }, ); }
4. 确保Hive序列化适配器正确生成
因为你的Local模型使用了Hive的注解(@HiveType、@HiveField),需要确保已经生成了对应的适配器:
- 执行命令生成适配器:
flutter packages pub run build_runner build
- 在App初始化时注册所有适配器:
void main() async { await Hive.initFlutter(); // 注册所有Local模型的适配器 Hive.registerAdapter(LocalProductsModelAdapter()); Hive.registerAdapter(LocalCategoriesModelAdapter()); Hive.registerAdapter(LocalImagesModelAdapter()); // 打开Hive盒子(如果还没打开) await Hive.openBox('cart'); runApp(MyApp()); }
注意:如果你的
LocalCategoriesModel和LocalImagesModel之前没有添加@HiveType和@HiveField注解,需要补上(参考下面的示例),否则Hive无法序列化这两个类型:
@HiveType(typeId: 1) // typeId要唯一,不能和其他模型重复 class LocalCategoriesModel { @HiveField(0) final int id; @HiveField(1) final String name; // 保留原有构造和方法... } @HiveType(typeId: 2) class LocalImagesModel{ @HiveField(0) final int id; @HiveField(1) final String src; @HiveField(2) final String name; // 保留原有构造和方法... }
这样修改后,就能顺利完成ProductsModel到LocalProductsModel的转换,并且正常存入和读取Hive本地存储了。
内容的提问来源于stack exchange,提问作者aJaysanity
相关产品推荐
相关产品推荐

