尧图精选

灯光模拟HarmonyOS应用实战-57-科二分类从两个入口传成两套:用PracticeQuery统一练习上下文

🕒 发布时间:2026/9/5 6:26:53 📁 来源:尧图网络
灯光模拟HarmonyOS应用实战-57-科二分类从两个入口传成两套用PracticeQuery统一练习上下文科二灯光练习同时存在两个入口主页模块进入后页面会默认选择“图标认知”顶部还能切换“上车检查”和“夜间场景”题库页则先选择科目再点击“开始练习”。两个入口最后都进入同一个startTheoryPractice()但它们携带分类的方式并不相同。前者把当前分类继续向下传递后者传入空字符串。只看最终页面两条路径都能出现题目很容易忽略它们建立的其实不是同一种练习上下文。这类问题的难点不在参数数量而在参数之间存在约束科目决定允许哪些分类模式决定页面标题和历史口径入口又决定“没有指定分类”究竟表示全部分类还是调用方忘记传值。如果继续让多个字符串在页面方法之间裸传新增入口时就只能靠开发者记住隐含规则。更稳的做法是把一次练习所需的信息收进PracticeQuery让构造、校验、选题和会话保存都围绕同一个不可拆散的快照工作。一、两条入口已经呈现出不同的分类语义Index.ets第338—397行只在科二页面展示分类标签。用户点击标签后代码先修改subject2Category再把科目、模式和标签文本传给开始方法。第477—513行的题库开始卡片则根据当前科目取得标题和模式最后一个参数固定传空字符串。第1116—1129行负责把这些值写入活动状态并选题。// 科二页内入口this.subject2Categorylabel;this.startTheoryPractice(SUBJECT_TWO,科二灯光基础,label);// 题库页入口this.openQuestionBankTest(this.questionBankSubject,this.getQuestionBankSubjectTitle(),this.getQuestionBankSubjectMode(),);privatestartTheoryPractice(subject:string,mode:string,category:string):void{this.activeSubjectsubject;this.activeModemode;this.activeQuestionsthis.selectTestQuestions(subject,category);}这段控制流说明分类既是页面选中态也是选题条件却没有成为一个有名称的业务概念。空字符串在selectQuestions()中会绕过分类比较因此当前效果接近“该科目全部分类”。这只是从源码条件表达式得到的静态结论它不能说明产品一定希望题库入口混合全部科二分类更不能说明用户已经遇到错误题目。入口当前分类来源向下传递值可读出的语义科二主页默认进入subject2Category 图标认知图标认知单一分类练习科二顶部标签用户点击的标签标签文本单一分类练习题库开始卡片没有分类控件当前实现中相当于全部分类将来错题复练可能来自历史记录尚无统一入口契约需要明确继承或覆盖规则二、三个字符串无法表达组合约束单看函数签名subject、mode、category都是合法字符串编译器无法阻止下面这些组合科一科目配“夜间场景”、科二模式配科四分类、空科目配非空分类。调用方还可能把页面标题误传到模式字段因为二者类型完全相同。真正需要维护的是组合不变量而不是单字段非空subject必须来自受支持科目集合。mode必须与科目匹配不能由任意页面文案代替。科二允许三个已登记分类科一和科四是否支持分类筛选要单独定义。“全部分类”应该是明确枚举不能借用空字符串。一旦会话启动查询快照不能再随页面标签变化。如果这些规则散落在CategoryChip()、题库卡片、openQuestionBankTest()和选题函数中任何一处新增分支都可能产生另一种解释。PracticeQuery的价值就在于给组合一个单独的校验入口。三、用判别联合写出分类范围先不要急着把三个字符串换成一个对象。对象仍然可以装入任意字符串只有类型把可选项和适用范围写清才能真正收紧入口。typePracticeSubjectsubject-one|subject-two|subject-four;typeSubjectTwoCategory图标认知|上车检查|夜间场景;typeCategoryScope|{kind:all}|{kind:subject-two;value:SubjectTwoCategory};typePracticeEntry|home-module|category-chip|question-bank|wrong-review;interfacePracticeQuery{subject:PracticeSubject;mode:string;category:CategoryScope;entry:PracticeEntry;}CategoryScope把“全部”与“科二具体分类”分成两个分支。后续代码必须先判断kind才能读取value不再靠category.length 0猜调用意图。entry不参与选题却能帮助历史与排障记录说明这次会话从哪里建立它应记录有限枚举不能保存页面对象、路由实例或用户输入全文。这里保留mode: string是迁移阶段的折中。如果工程已经有稳定模式常量可以进一步收窄为联合类型若模式文本还承担展示职责应先分出稳定的modeId和本地化标题避免一次改造同时改变过多层。四、查询工厂集中处理科目、模式与分类页面不应直接拼装任意PracticeQuery。建立一个小型工厂让各入口只能提交自己真实拥有的信息再由工厂补齐模式并验证分类归属。interfacePracticeQueryResult{ok:boolean;query?:PracticeQuery;reason?:UNSUPPORTED_SUBJECT|CATEGORY_NOT_ALLOWED;}constSUBJECT_TWO_CATEGORIES:SubjectTwoCategory[][图标认知,上车检查,夜间场景];functionisSubjectTwoCategory(value:string):valueisSubjectTwoCategory{returnSUBJECT_TWO_CATEGORIES.indexOf(valueasSubjectTwoCategory)0;}functioncreateSubjectTwoQuery(category:string,entry:PracticeEntry):PracticeQueryResult{if(!isSubjectTwoCategory(category)){return{ok:false,reason:CATEGORY_NOT_ALLOWED};}return{ok:true,query:{subject:subject-two,mode:科二灯光基础,category:{kind:subject-two,value:category},entry}};}工厂拥有科二分类白名单因此页面标签与题库种子使用的分类名称发生漂移时会在会话开始前返回明确原因。它不擅自把未知分类改成“全部”因为静默降级会掩盖配置错误。实际接入时还应让标签数据也从同一分类目录生成避免类型数组和 UI 文案再复制一份。PracticeQueryResult使用可选字段是为了展示业务结果形态。正式实现可改成更严格的判别联合让ok: true分支必有queryok: false分支必有reason选择哪种写法要以工程当前 ArkTS 规则和目标 SDK 编译结果为准。五、把每个页面入口改造成薄适配器工厂建立后页面只负责收集交互值和处理失败不再决定选题规则。科二分类标签可以传精确分类题库入口则要由产品语义决定是默认某一类还是明确选择全部。privatestartFromSubjectTwoChip(label:string):void{constresultcreateSubjectTwoQuery(label,category-chip);if(!result.ok||result.queryundefined){this.answerMessage该分类暂不可用;return;}this.beginPractice(result.query);}privatestartSubjectTwoFromBank():void{constquery:PracticeQuery{subject:subject-two,mode:科二灯光基础,category:{kind:all},entry:question-bank};this.beginPractice(query);}第二个适配器显式写出kind: all这不代表产品必须保留当前混合行为而是让选择可见、可审阅。如果产品希望题库入口沿用上次科二分类就应该从稳定的偏好设置读取合法枚举读取失败时给出明确默认值不能继续把空字符串同时当作“全部”“没有选择”和“读取失败”。六、题目选择器只消费查询不读取页面字段目前startTheoryPractice()先写多个响应式字段再调用selectTestQuestions(subject, category)。改造后选择器应只接收已经通过入口校验的查询快照。这样即使用户快速切换标签正在建立的会话也不会在一半流程里读到新分类。functionselectByPracticeQuery(source:QuestionItem[],query:PracticeQuery):QuestionItem[]{constresult:QuestionItem[][];for(letindex0;indexsource.length;index){constquestionsource[index];if(question.subject!query.subject){continue;}if(query.category.kindsubject-twoquestion.category!query.category.value){continue;}result.push(question);}returnresult;}选择器不再知道subject2Category、questionBankSubject或当前页面。它只比较题目字段与查询字段因此可以在不创建 ArkUI 页面的情况下验证。还要注意示例中的PracticeSubject值需要与工程真实SUBJECT_TWO常量做适配不能把文章里的字符串直接替换进现有数据后假定兼容。若返回空数组调用方必须区分“这个合法分类目前没有题”和“查询不合法”。前者属于内容缺口后者属于入口错误两种情况都不应自动回退到另一分类更不能补入内置第一题。七、会话一次性提交状态避免半更新查询完成并取得题目后再生成会话启动结果。页面只提交一次完整快照而不是先改activeSubject、再改activeMode、最后等待题目数组出现。interfacePracticeStartSnapshot{query:PracticeQuery;questions:QuestionItem[];firstIndex:number;initialMessage:string;}typePracticeStartResult|{kind:ready;snapshot:PracticeStartSnapshot}|{kind:empty;query:PracticeQuery}|{kind:rejected;reason:string};functionpreparePractice(query:PracticeQuery,catalog:QuestionItem[]):PracticeStartResult{constquestionsselectByPracticeQuery(catalog,query);if(questions.length0){return{kind:empty,query};}return{kind:ready,snapshot:{query,questions,firstIndex:0,initialMessage:请选择答案}};}这个结果把“准备”与“提交”分开。preparePractice()是纯计算可以核对输入输出页面拿到ready后再一次性更新活动查询、题目、索引、已选答案和提示文案。empty分支保留原查询UI 才能告诉用户究竟哪个分类没有内容而不是只显示一个没有上下文的空页。八、历史与重进保存稳定查询快照会话开始后应把PracticeQuery视为只读事实。历史记录可以保存科目、分类范围和入口但不应在展示时重新读取当前标签。重进练习时还要重新校验旧分类可能在新版本中被移除旧模式名称也可能已经迁移。interfaceStoredPracticeContextV1{schemaVersion:1;subject:PracticeSubject;categoryKind:all|subject-two;categoryValue?:SubjectTwoCategory;entry:PracticeEntry;}functiontoStoredContext(query:PracticeQuery):StoredPracticeContextV1{return{schemaVersion:1,subject:query.subject,categoryKind:query.category.kind,categoryValue:query.category.kindsubject-two?query.category.value:undefined,entry:query.entry};}存储对象只包含稳定枚举不保存页面标题也不保存QuestionItem[]的整份副本。恢复时根据schemaVersion迁移再交给查询工厂核对。若旧数据缺少分类迁移规则必须明确选择all或某个产品默认值并记录这是兼容决定不能假装旧记录原本就携带了分类。九、用入口矩阵验证上下文不会漂移这次改造不能只核对“能进入页面”。需要把每个入口、分类切换、空题组和快速操作都放进矩阵观察最终快照和题目集合是否一致。编号操作应形成的查询应观察到的结果P57-01从科二模块首次进入科二、图标认知、主页入口只出现图标认知题P57-02点击“上车检查”科二、上车检查、标签入口新会话快照完整替换旧快照P57-03从题库选择科二并开始科二、明确的 all 或产品默认分类行为与产品规则一致不依赖空串P57-04传入未知分类工厂拒绝不启动、不回退、不写历史P57-05合法分类没有题empty页面展示科目与分类并允许返回P57-06启动过程中快速切换标签原查询被冻结已开始会话不被新标签污染P57-07从历史重进旧分类迁移后查询合法时恢复失效时给出恢复入口P57-08科一入口误传科二分类组合校验拒绝不出现跨科目题目除结果数组外还应核对两个不变量所有题目的subject必须等于查询科目当分类分支是subject-two时所有题目的category必须等于查询分类。若选择器后面还会洗牌或截取这两个不变量应在最终会话数组上再核对一次。十、验证清单、排障表与事实边界所有练习入口都通过查询工厂或明确适配器建立PracticeQuery。“全部分类”使用显式分支不再借用空字符串。科二分类名称来自单一目录UI 与题库不各存一份。非法科目与分类组合在选题前被拒绝。选择器只消费查询和题目目录不读取页面响应式字段。会话状态由一个完整快照提交不产生半更新画面。空题组保留原查询并显示准确恢复入口。历史只保存稳定枚举和版本不保存页面对象或完整题库。快速切换、返回重进和旧数据迁移都有独立用例。目标 SDK 下的联合类型、集合写法和 ArkUI 状态提交方式经过文档与编译复核。症状优先检查常见原因处理方向同为科二入口却出现不同题组category.kind一个入口传具体分类另一个仍传空串统一由适配器构造查询点击未知分类后出现全部题工厂失败分支非法值被降级为 all明确拒绝并保留当前会话切换标签后旧会话题目变化查询是否冻结选择器读取了页面当前字段会话保存不可变查询快照历史卡片分类与实际题目不符历史字段来源展示时读取当前标签从已提交查询映射历史空分类恢复成内置第一题空结果处理仍存在隐式兜底返回empty并停止提交新增第四个科二分类后入口不一致分类目录UI、工厂和题库分别维护用同一目录生成选项并做差异审阅旧记录无法重进schemaVersion旧数据没有分类范围写清迁移规则并提供安全退出当前源码可以确认科二页内分类标签会把具体标签传入startTheoryPractice()题库开始卡片会把分类传为空字符串开始方法再用科目与分类选择题目。这些是指定源码行的静态事实不等于已经在设备上观察到跨分类故障。本文提出的PracticeQuery、查询工厂、入口适配器、准备结果和存储快照均为建议方案尚未合入或写入The_kemusan。本次未构建项目没有生成新的 HAP也没有在模拟器或真机上验证科二入口、快速切换、历史重进和空题组行为。真正接入后仍需依据目标 SDK 文档、编译结果和设备操作补齐证据。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →