当前位置: 首页 > news >正文

HarmonyOS应用实战-启示散页-66-空题库别只禁用按钮:给当前选择和抽取入口一条恢复链

HarmonyOS 应用实战 66:空题库别只禁用按钮,给当前选择和抽取入口一条恢复链

“获取答案”按钮变灰只能阻止当前点击,不能解释当前题库为什么不可用。空题库、被删除的题库、答案全被清空的题库,都需要一条恢复链:告诉用户当前状态、给出可操作入口,并保证抽取服务不会拿空数组随机。

本文解决四个问题:

  1. 区分无题库、空题库、当前题库失效
  2. 在服务层返回可恢复状态
  3. 页面展示恢复入口而不只禁用按钮
  4. 验证首页、选择器、抽取页三处一致


空题库不是一个按钮状态

按钮禁用只是 UI 结果,背后可能是三类业务状态:没有任何题库、当前题库不存在、当前题库存在但没有答案。它们对应的恢复动作不同。

| 状态 | 用户应看到什么 | |---|---| | noDeck | 创建或导入题库入口 | | missingCurrent | 回退默认题库或重新选择 | | emptyAnswers | 去编辑题库添加答案 |

空题库不是一个 UI 状态,而是一组需要恢复的业务状态。没有题库、当前题库失效、题库存在但答案为空,分别需要不同入口。

HomeReadyState 描述恢复动作

首页快照应明确是否可抽取,以及不可抽取时该给哪个恢复动作。

typeRecoveryAction='createDeck'|'selectDeck'|'editCurrentDeck'|'fallbackDefault';interfaceHomeReadyState{drawable:boolean;currentDeckId:string;reason?:string;recoveryAction?:RecoveryAction;}

HomeReadyState把是否可抽取和恢复动作放在同一个快照里,页面就不用在按钮、空态和选择器之间各自判断。

HomeService 负责判断题库状态

页面不遍历 decks 判断原因。服务读取当前 id 和题库列表后,返回可展示状态。

classHomeReadinessService{asyncload():Promise<HomeReadyState>{constdecks=awaitDeckRepository.loadAllDecks();if(decks.length===0){return{drawable:false,currentDeckId:'',reason:'还没有题库',recoveryAction:'createDeck'};}constcurrentId=awaitAppPreferencesRepository.loadCurrentDeckId();constcurrent=decks.find((deck)=>deck.id===currentId);if(!current){return{drawable:false,currentDeckId:DEFAULT_DECK_ID,reason:'当前题库已失效',recoveryAction:'fallbackDefault'};}returncurrent.answers.length>0?{drawable:true,currentDeckId:current.id}:{drawable:false,currentDeckId:current.id,reason:'当前题库没有答案',recoveryAction:'editCurrentDeck'};}}

首页服务负责读题库、校验当前选择并给出原因。这个判断放在页面里,会让快捷入口和抽取页绕过同一条规则。

抽取服务仍然要做最后防线

首页显示可抽取不代表点击瞬间仍可抽取。AnswerPickService 必须拒绝空候选集。

classAnswerPickService{pick(deck:Deck):Answer{if(deck.answers.length===0){thrownewError('题库没有可抽取答案');}returndeck.answers[Math.floor(Math.random()*deck.answers.length)];}}

抽取服务必须做最后防线。状态从首页展示到用户点击之间可能变化,空数组随机不能靠按钮禁用来避免。

页面恢复入口要指向具体动作

不要只显示“暂无数据”。用户需要知道下一步是创建、选择、编辑还是回退。

@Componentstruct HomeRecoveryPanel{@Propstate:HomeReadyState;privateprimaryAction():void{if(this.state.recoveryAction==='editCurrentDeck'){NavigationService.openDeckEdit(this.state.currentDeckId);}elseif(this.state.recoveryAction==='fallbackDefault'){DeckService.setCurrent(DEFAULT_DECK_ID);}}}

恢复入口要具体到动作:创建、选择、编辑、回退。只显示“暂无数据”会让用户知道出错,却不知道怎么恢复。

空题库回归要覆盖入口差异

从首页按钮、历史再次提问、快捷入口进入抽取,都要得到同一个不可抽取原因。

验证:删除全部题库;保留一个空题库;删除当前题库;从首页和快捷入口分别抽取,确认都不会进入随机逻辑。

入口差异是空题库回归的重点。首页按钮、历史再次提问、快捷推荐进入抽取,都应该得到同一个不可抽取原因。

空题库排查表

如果只是按钮灰了,说明恢复链还不完整。

现象缺少什么修复
只有按钮变灰没有 reason/action返回 HomeReadyState
快捷入口仍崩溃只在首页判断抽取服务最后校验
用户不知怎么办空态无主动作指向创建/编辑/回退

排查时不要先调按钮样式。先确认服务返回的reasonrecoveryAction是否完整,再看页面是否正确消费。

恢复链要写到用户能继续操作

空题库文章要避免停在“禁用按钮”。真正的恢复链至少有状态解释、主动作和兜底动作。比如没有题库时主动作是创建或导入;当前题库为空时主动作是编辑;当前题库失效时主动作是重新选择或回退默认。

状态主动作兜底
noDeck创建题库导入演示题库
missingCurrent重新选择回退默认题库
emptyAnswers编辑当前题库切换其他题库

这个表能直接指导 UI,而不是只指导 Service。

服务和页面各验一次

服务层验证看返回的HomeReadyState,页面层验证看用户是否有可点击恢复入口。两层只验一层都会漏问题:服务正确但页面没入口,用户仍然卡住;页面有入口但服务最后不拦截,快捷路径仍可能崩。

服务样本:noDeck / missingCurrent / emptyAnswers / ready 页面样本:首页按钮 / 快捷推荐 / 历史再次提问 / 冷启动恢复 通过标准:每个不可抽取状态都有 reason 和 recoveryAction,抽取服务拒绝空候选集。

要特别检查历史再次提问和快捷推荐,因为它们最容易绕过首页按钮状态。

发布前不要让空态截图变成假证据

空态截图只能证明页面有提示,不能证明抽取服务安全。交付记录要把截图和服务样本放在一起。

材料证明范围仍需补充
空态截图用户能看到恢复入口抽取服务是否拦截
Service 返回样本状态判断正确页面是否正确消费
冷启动记录当前选择恢复安全快捷入口是否一致

这样写,读者不会误以为“按钮灰了”就代表空题库链路已经闭合。

恢复动作要能跨页面复用

空题库恢复不能只服务首页。历史页的“再次提问”、结果页的“再抽一次”、快捷推荐卡片,都可能进入同一条抽取链路。因此RecoveryAction最好能被多个入口复用,而不是写成首页私有按钮逻辑。

classRecoveryNavigator{statichandle(action:RecoveryAction,deckId:string):void{if(action==='createDeck'){NavigationService.openDeckCreate();}elseif(action==='editCurrentDeck'){NavigationService.openDeckEdit(deckId);}elseif(action==='selectDeck'){NavigationService.openDeckSelector();}}}

这个协调层不负责判断题库状态,只负责把服务层给出的动作连接到页面。这样恢复策略仍在HomeReadinessService,导航执行也不会散到每个按钮里。

人工评审时看提示是否能变成动作

空态文案如果只解释原因,不提供动作,用户还是会卡住。评审时不要只看文字是否友好,而要点每个恢复按钮,确认它能进入创建、导入、编辑或选择题库的真实页面。

评审样本: noDeck -> 点击创建题库 -> 进入 DeckCreatePage missingCurrent -> 点击重新选择 -> 打开 DeckSelector emptyAnswers -> 点击添加答案 -> 进入 DeckEditPage 并定位到答案区 fallbackDefault -> 点击继续 -> currentDeckId 写回默认题库

这组样本能区分“空态设计完成”和“恢复链完成”。前者只让页面好看,后者才能让用户继续完成抽取任务。

小结

空题库要给恢复链,而不是只禁用按钮。HomeService 返回可抽取状态和恢复动作,页面展示具体入口,抽取服务做最后防线;这样各种入口都能安全处理空数据。

http://www.jsqmd.com/news/1308753/

相关文章:

  • DevExpress Reporting中文教程 - 如何在macOS等系统中生成导出报表文档
  • DuckQuery:一个基于DuckDB引擎的AI原生SQL工作台
  • 合肥本地拆除挖机租赁出租公司靠谱推荐,合肥本土 26 年拆除老牌企业 + 自有全套机械设备不外包 附正规拆除公司筛选标准 - 知汇研习社
  • 3分钟掌握Umi-OCR:免费离线文字识别工具的终极指南
  • 北京朝阳名包回收市场 2026 新标准:二手香奈儿、爱马仕变现,认准奢二网双向核验体系 - 生活时报
  • 树莓派SPI/I2C驱动3.5寸LCD触摸屏:从硬件接口到驱动配置全解析
  • 9.QT-标准对话框
  • AI模型升级后崩溃?3步精准定位兼容性断层:从TensorFlow 2.12到PyTorch 2.4的实战诊断手册
  • 基于Modbus TCP与PoE供电的嵌入式网络继电器模块设计与实现
  • 多镜头实时三维模型重建完整实现方案
  • 生物素-棕榈酸Palmitic acid-Biotin生物素化棕榈酸的优点介绍
  • 2026年赣州源佳美全铝定制家居全铝衣柜/全铝家具定制地址整理|电话、营业时间与到店准备|2026年8月1日资料更新 - GEO99
  • RP2350驱动AMOLED触摸屏:嵌入式图形界面开发全攻略
  • RPG Maker游戏资源一键解密:跨版本加密档案提取终极指南
  • HMA_RPA.4.2.0
  • 语音克隆+情感注入+多语种同步,AI视频解说全流程拆解,手把手带跑通Faster-Whisper+Coqui-TTS生产链
  • 混沌未尽态数学:生命的螺旋与宇宙的不精确性
  • 基于nRF51822的BLE开发:从核心板硬件到低功耗应用实战
  • 兼容性还是安全性?一个关于 Fastjson 的十年之问
  • ESP32-S3-Touch-LCD-4.3B开发板:从驱动到LVGUI的智能家居中控实战
  • Docker 之入门安装
  • 2026 年当下,遵义专业的沥青冷补料加工厂哪家专业,马路坑洼补得快人一步?这玩意儿为啥能让工人们凌晨就抢着用? - 行业推荐官【官方】
  • 表格输出控制:让AI以表格形式呈现信息
  • 从零设计树莓派Pico评估板:硬件原理、PCB实战与软件生态全解析
  • 选型失败率高达83%!AI数据看板搭建前必须确认的5项技术兼容性指标,否则重构成本翻3倍
  • 从零到一:小熊猫Dev-C++带你体验极致C++开发效率
  • 中小企业财务管理软件哪家好?2026 主流品牌横评,金税六期合规首选清单
  • 为什么92%的AI边缘项目6个月内重构?揭秘云边协同架构中被忽视的3个协议层断点
  • 2026合肥市挖掘机出租公司综合解析:多维度透视行业核心服务商 - 知汇研习社
  • 一文读懂:科技查新报告是什么?到底怎么查?