Flutter Isar热重启后取消星标功能失效问题求助
Flutter Isar 热重启后无法取消已标星项目的问题解决
问题描述
刚学习Flutter Isar并制作了演示应用,应用包含两个板块:
- Original:存放假数据dummyData
- Database:展示Isar数据库中的数据
正常状态下,在Original板块给项目标星时,项目会添加到数据库,图标切换为实心星;取消星标时从数据库移除,图标切换为空心星,功能正常。但热重启后无法取消已标星的项目。
问题根源
热重启后,dummyData中的Course对象的id仍保持初始值Isar.autoIncrement(即0),但数据库中存储的对应Course已经被Isar分配了真实的自增ID。调用deleteCourse方法时,传入的是dummyData里的Course对象,用其无效的id(0)去删除,自然无法找到数据库中的对应实体,导致删除失败,图标也不会切换。
解决方案
1. 修改IsarService中的删除逻辑
将deleteCourse方法改为通过courseId查找数据库中的对应实体,再进行删除:
// isar.dart Future<void> deleteCourse(String courseId) async { final isar = await _db; // 通过courseId精准匹配找到要删除的实体 final courseToDelete = await isar.courses.filter().courseIdEqualTo(courseId).findFirst(); if (courseToDelete != null) { await isar.writeTxn(() async { await isar.courses.delete(courseToDelete.id); }); } }
同时优化isItemDuplicate方法,使用精准匹配避免部分匹配的潜在问题:
// isar.dart Future<bool> isItemDuplicate(Course course) async { final isar = await _db; final courseExists = await isar.courses.filter().courseIdEqualTo(course.courseId).findFirst(); return courseExists != null; }
2. 修改调用删除方法的代码
- 在
onFavTap中,传入courseId而非整个Course对象:
// main.dart Future<void> onFavTap(IsarService courseData, Course course) async { if (await courseData.isItemDuplicate(course)) { // 改为传入courseId await courseData.deleteCourse(course.courseId); setState(() {}); debugPrint('${course.courseId} deleted'); } else { await courseData.addCourse(course); setState(() {}); debugPrint('${course.courseId} added'); } }
- 在Database板块的删除逻辑中,同样传入
courseId:
// main.dart 中Database板块的ListTile trailing: InkWell( onTap: () async { await courseData.deleteCourse(snapshot.data![index].courseId); setState(() {}); }, child: const Icon(Icons.star)),
补充说明
这样修改后,无论是否热重启,都能通过唯一的courseId精准定位到数据库中的实体,确保删除操作生效,图标也能正确切换。
内容的提问来源于stack exchange,提问作者thebigbrownBox
相关产品推荐
相关产品推荐

