mirror of
https://github.com/panatgithub/AnkiHeadingSync.git
synced 2026-07-22 17:10:28 +00:00
4.8 KiB
4.8 KiB
设置页 Anki 模板缓存实现决策
本文锁定本轮“设置页 Anki 模板加载性能优化”的仓库兼容实现方案。
1. 设置模型新增字段缓存
- 保留现有
ankiNoteTypeCache: string[]。 - 新增:
ankiModelFieldCache: Record<string, { fieldNames: string[]; loadedAt: number }>
- 该缓存只用于设置页 UI 加速。
- 同步路径继续通过 live
getModelDetails()做实时校验。
2. 字段缓存 normalize 规则
ankiNoteTypeCache:- 继续 trim
- 过滤空字符串
- 去重
- 按稳定字典序保存
ankiModelFieldCache:- 只接受对象
- key 只保留 trim 后非空的模型名
fieldNames只保留字符串项- 对每个模型内的字段名:trim、过滤空项、去重,保留原出现顺序
loadedAt非有限数字时回退为 0- 最终按模型名字典序稳定输出
3. validate 规则
- 对
ankiModelFieldCache做结构校验:- 顶层必须是对象
- 每个模型缓存值必须是对象
fieldNames必须是数组- 数组项必须全是字符串
loadedAt必须是有限数字
- normalize 负责“纠偏和过滤”;validate 负责拒绝直接传入的非法结构。
4. gateway 接口设计
- 在
AnkiGroupGateway中新增:getModelFieldNamesByModelNames(modelNames: string[]): Promise<Record<string, string[]>>
AnkiConnectGateway内部使用一次multi请求发送多个modelFieldNamesaction。- 单个 action 若返回
{ error }:跳过该模型。 - 顶层
multi若失败:抛错。 - 本轮不重构通用
invokeMulti();新增一个专门解析该响应的方法,降低行为风险。
5. 设置页卡片 1 的数据来源
- 页面打开时:
- note type 下拉来自
ankiNoteTypeCache - field 下拉来自
ankiModelFieldCache[selectedModel].fieldNames
- note type 下拉来自
- 若字段缓存存在,则在设置页内即时水合为
loadedModelDetails/ draft mapping 可消费的形态。 - 若某个已选模板没有字段缓存:
- 不阻塞渲染
- 直接显示“请先读取字段”占位
6. 手动刷新按钮的精确流程
- 点击按钮后:
listNoteModels()一次getModelFieldNamesByModelNames(modelNames)一次- 将两份缓存合并成一次
updateSettings()
- 保存成功后:
- 刷新当前设置页实例内的
availableNoteModels - 用字段缓存为 3 个可见卡片类型生成或刷新 draft mapping
- 状态显示:
x = 模板数量y = basic / qa-group / cloze 中,所选模板已有字段缓存的数量
- 刷新当前设置页实例内的
- 不再在按钮流程里默认调用
getNoteModelDetails()。 - 不再在按钮流程里默认调用
modelTemplates()。
7. 切换 note type 后的行为
- 切换模板仍立即保存
cardTypeConfigs[configId].noteType。 - 保存后卡片 1 会局部重渲染。
- 若新模板在
ankiModelFieldCache中已有字段缓存:- 字段下拉立即显示缓存字段
- draft mapping 若尚不存在,则用
NoteFieldMappingService.suggest()现算一份 UI draft
- 不因为只是切换下拉而立刻访问 AnkiConnect。
8. QA Group 行与可见卡片范围
- 继续维持当前设置页只展示三行:
basicqa-groupcloze
- 不把
semantic-qa加回设置页,避免超出本轮范围。 qa-group当前仓库已经允许普通 note type / 字段映射编辑;本轮不扩大为产品改动,只沿用仓库现状。
9. Cloze 边界
- 设置页只需要字段名缓存和字段建议。
- Cloze 完整兼容性校验继续留在同步链路:
getModelDetails()isCloze判定
- 本轮不把 Cloze 严格校验搬到设置页刷新按钮里。
10. 卡片 1 局部刷新策略
- 按钮加载状态只存在于 card 1。
- 刷新操作前后只调用
renderCard("card-types")。 - 不调用整页
display()。 - 缓存保存尽量合并成一次
updateSettings(),避免按钮流程内多次写 settings。
11. 测试决策
- 配置层:补
ankiModelFieldCache默认值、normalize、validate 覆盖。 - gateway:为新批量字段接口单独补
multi请求与解析测试。 - 设置页:新增缓存优先渲染、刷新按钮调用次数、状态文案、切换模板后即时字段缓存生效等断言。
12. 与原计划的受控偏离
- 原计划写到“semantic-qa 继续不显示在设置页”,当前仓库确实只显示三行,因此保持不变。
- 原计划提到“当前 3 个可见卡片类型”,但仓库里的三行是
basic / qa-group / cloze,不是basic / cloze / semantic-qa;本轮按仓库真实 UI 执行。 - 原计划说 QA Group 行是托管模型,但当前仓库已经允许 QA Group 行编辑 note type 和字段映射。为了不扩大产品行为回退范围,本轮不顺手收紧它,只做缓存与批量读取优化。