基于HarmonyOS的情侣美食管理应用开发实战(十三)- 修复主页菜谱列表不显示问题 📅 2026/7/12 23:02:39 基于HarmonyOS的情侣美食管理应用开发实战一- 修复主页菜谱列表不显示问题问题现象在 HarmonyOS 应用开发过程中遇到了一个奇怪的问题主页我的菜谱模块显示共4个但列表区域完全空白菜谱分类页面点进分类后可以正常显示菜谱列表数据库确认有菜谱数据存在这个问题看起来很矛盾为什么分类页面能显示主页却不能问题分析1. 数据加载流程对比首先对比主页和分类页面的数据加载流程主页加载流程// ChefHomePage.etsasyncloadRecipes(){this.isLoadingtruetry{this.recipesawaitRdbUtil.queryAllRecipes()// 查询所有菜谱LogUtil.info(ChefHomePage,加载完成共${this.recipes.length}个菜谱)}catch(err){LogUtil.error(ChefHomePage,加载菜谱失败:${JSON.stringify(err)})}finally{this.isLoadingfalse}}分类页面加载流程// RecipeTypePage.etsasyncloadRecipes(){this.isLoadingtruetry{this.recipesawaitRdbUtil.queryRecipesByType(this.type)// 按类型查询LogUtil.info(RecipeTypePage,加载完成共${this.recipes.length}个菜谱)}catch(err){LogUtil.error(RecipeTypePage,加载菜谱失败:${JSON.stringify(err)})}finally{this.isLoadingfalse}}2. 数据库查询方法对比检查两个数据库查询方法的实现查询所有菜谱staticasyncqueryAllRecipes():PromiseRecipe[]{constpredicatesnewrelationalStore.RdbPredicates(recipe)predicates.orderByDesc(create_time)constresultSetawaitRdbUtil.rdbStore.query(predicates)constrecipes:Recipe[][]while(resultSet.goToNextRow()){constrecipenewRecipe()recipe.idresultSet.getLong(resultSet.getColumnIndex(id))recipe.nameresultSet.getString(resultSet.getColumnIndex(name))// ... 其他字段recipes.push(recipe)}resultSet.close()returnrecipes}按类型查询菜谱staticasyncqueryRecipesByType(type:number):PromiseRecipe[]{constpredicatesnewrelationalStore.RdbPredicates(recipe)predicates.equalTo(type,type)predicates.orderByDesc(create_time)constresultSetawaitRdbUtil.rdbStore.query(predicates)constrecipes:Recipe[][]while(resultSet.goToNextRow()){constrecipenewRecipe()recipe.idresultSet.getLong(resultSet.getColumnIndex(id))recipe.nameresultSet.getString(resultSet.getColumnIndex(name))// ... 其他字段recipes.push(recipe)}resultSet.close()returnrecipes}3. 发现问题经过仔细对比发现了关键问题queryRecipesByType()方法缺少orderCount字段的读取// queryAllRecipes() 中有这行recipe.orderCountresultSet.getLong(resultSet.getColumnIndex(order_count))// queryRecipesByType() 中缺少这行// recipe.orderCount resultSet.getLong(resultSet.getColumnIndex(order_count))虽然这个字段缺失不应该直接导致列表不显示但它反映了代码的不一致性可能影响后续的数据处理。解决方案方案一统一数据库查询遍历方式首先统一了两个查询方法的遍历方式使用while (resultSet.goToNextRow())// 修改前使用 do-whileif(resultSet.rowCount0){if(resultSet.goToFirstRow()){do{// 读取数据}while(resultSet.goToNextRow())}}// 修改后使用 whilewhile(resultSet.goToNextRow()){// 读取数据}方案二补全缺失字段在queryRecipesByType()方法中补全orderCount字段staticasyncqueryRecipesByType(type:number):PromiseRecipe[]{// ...while(resultSet.goToNextRow()){constrecipenewRecipe()recipe.idresultSet.getLong(resultSet.getColumnIndex(id))recipe.nameresultSet.getString(resultSet.getColumnIndex(name))recipe.typeresultSet.getLong(resultSet.getColumnIndex(type))recipe.descriptionresultSet.getString(resultSet.getColumnIndex(description))recipe.imagePathresultSet.getString(resultSet.getColumnIndex(image_path))recipe.imagerecipe.imagePath recipe.cookingTimeresultSet.getLong(resultSet.getColumnIndex(cooking_time))recipe.difficultyresultSet.getLong(resultSet.getColumnIndex(difficulty))recipe.isFavoriteresultSet.getLong(resultSet.getColumnIndex(is_favorite))recipe.orderCountresultSet.getLong(resultSet.getColumnIndex(order_count))// ✅ 补全recipe.createTimeresultSet.getLong(resultSet.getColumnIndex(create_time))recipe.updateTimeresultSet.getLong(resultSet.getColumnIndex(update_time))recipes.push(recipe)}// ...}技术要点1. HarmonyOS ResultSet 遍历方式HarmonyOS 的ResultSet提供了两种遍历方式方式一使用goToNextRow()while(resultSet.goToNextRow()){// 读取当前行数据}方式二使用goToFirstRow()goToNextRow()if(resultSet.goToFirstRow()){do{// 读取当前行数据}while(resultSet.goToNextRow())}两种方式都是正确的但推荐使用第一种方式代码更简洁。2. 数据模型字段完整性在从数据库读取数据时必须确保所有字段都要读取避免数据不完整字段类型要匹配数据库字段类型要与模型字段类型一致字段名称要对应数据库列名要与getColumnName()参数一致3. 日志调试技巧在数据加载方法中添加详细日志有助于快速定位问题asyncloadRecipes(){LogUtil.info(ChefHomePage,开始加载菜谱列表)this.isLoadingtruetry{this.recipesawaitRdbUtil.queryAllRecipes()LogUtil.info(ChefHomePage,加载完成共${this.recipes.length}个菜谱)}catch(err){LogUtil.error(ChefHomePage,加载菜谱失败:${JSON.stringify(err)})}finally{this.isLoadingfalse}}经验总结1. 代码一致性的重要性相同功能的方法应该保持一致queryAllRecipes()和queryRecipesByType()应该使用相同的实现模式避免遗漏字段所有查询方法都应该读取完整的字段列表定期代码审查及时发现和修复不一致的地方2. 调试思路遇到类似问题时可以按照以下步骤调试对比正常和异常场景分类页面能显示主页不能显示检查数据加载流程对比两个页面的数据加载方法检查数据库查询对比两个查询方法的实现检查字段完整性确保所有字段都被正确读取添加日志输出在关键位置添加日志跟踪数据流3. HarmonyOS 开发注意事项ResultSet 必须关闭使用完毕后要调用resultSet.close()异步操作要 await数据库查询是异步操作要正确使用await错误处理要完善使用 try-catch 捕获异常避免应用崩溃最终代码修复后的queryRecipesByType()方法staticasyncqueryRecipesByType(type:number):PromiseRecipe[]{if(!RdbUtil.rdbStore){LogUtil.error(RdbUtil.TAG,数据库未初始化)return[]}try{constpredicatesnewrelationalStore.RdbPredicates(recipe)predicates.equalTo(type,type)predicates.orderByDesc(create_time)constresultSetawaitRdbUtil.rdbStore.query(predicates)constrecipes:Recipe[][]while(resultSet.goToNextRow()){constrecipenewRecipe()recipe.idresultSet.getLong(resultSet.getColumnIndex(id))recipe.nameresultSet.getString(resultSet.getColumnIndex(name))recipe.typeresultSet.getLong(resultSet.getColumnIndex(type))recipe.descriptionresultSet.getString(resultSet.getColumnIndex(description))recipe.imagePathresultSet.getString(resultSet.getColumnIndex(image_path))recipe.imagerecipe.imagePath recipe.cookingTimeresultSet.getLong(resultSet.getColumnIndex(cooking_time))recipe.difficultyresultSet.getLong(resultSet.getColumnIndex(difficulty))recipe.isFavoriteresultSet.getLong(resultSet.getColumnIndex(is_favorite))recipe.orderCountresultSet.getLong(resultSet.getColumnIndex(order_count))recipe.createTimeresultSet.getLong(resultSet.getColumnIndex(create_time))recipe.updateTimeresultSet.getLong(resultSet.getColumnIndex(update_time))recipes.push(recipe)}resultSet.close()returnrecipes}catch(err){LogUtil.error(RdbUtil.TAG,按类型查询菜谱失败:${err})return[]}}测试验证修复后需要验证以下功能✅主页我的菜谱能正常显示所有菜谱✅菜谱分类页面能正常显示各分类的菜谱✅菜谱数量显示数量与实际数量一致✅菜谱详情能正常查看菜谱详细信息结语这个问题看似简单但暴露了代码一致性的重要性。在开发过程中我们应该保持代码风格一致相同功能的方法使用相同的实现模式定期代码审查及时发现和修复不一致的地方完善测试覆盖确保所有功能都经过充分测试重视日志输出在关键位置添加日志方便问题定位希望这篇博客能帮助遇到类似问题的开发者快速定位和解决问题