在这里插入图片描述

前言

编辑任务最常见的 bug,是用户点击一张卡片的编辑按钮后,另一张卡片的输入内容也跟着变化。更隐蔽的问题是:编辑输入和新增输入共用一个变量,用户点了取消,下一次打开页面时旧标题又出现在输入框里。编辑功能的关键不是再放一个按钮,而是明确“正在编辑哪一个任务”和“当前表单是否已经提交”。

这篇文章继续沿着当前 Taskflow 待办面板往前走。和只展示 API 名称的教程不同,文章会把用户动作、状态变化、布局结果和验证证据放在同一条链上。读者可以先看“当前边界”判断哪些内容能直接复制,再看“下一步设计”区分哪些能力还需要自己接入。这样做的目的不是降低目标,而是避免把一个尚未运行的方案误写成项目结论。

先把问题拆成输入、变化和结果

editingId 表示编辑对象,而不是保存一个可变的任务引用。编辑输入是临时状态,提交后才通过稳定 id 替换源数组中的记录。这样筛选和搜索不会改变编辑对象的身份,列表重排也不会把输入写到错误的卡片。

在实现之前,建议把问题写成三列。输入是用户能改变的值,例如筛选项、关键词、标题、复选框和按钮动作;变化是页面内部要更新的源数据或异步状态;结果是用户能看到、能继续操作、能在重启后复查的内容。只要这三列没有对齐,代码就会出现“事件触发了但列表没有变”“数据显示了但重启丢失”这类难以解释的现象。

对于当前工程,源数据仍然是 TodoItem[]。筛选、搜索和编辑输入属于页面状态,任务数组的新增、替换、删除和恢复属于写入动作,Preferences 只负责把任务事实序列化保存。这个边界贯穿本系列后续文章,也解释了为什么不能为了方便给每一个视图再复制一份数组。

当前项目边界

当前 App 已实现行内编辑:点击卡片的“编辑”后,标题进入顶部输入框,按钮切换为“保存修改”,同时显示“取消”。保存时只更新任务标题,保留原任务的 id、分类、时间、优先级和完成状态;取消时清理编辑状态。

文章里出现“已实现”时,指的是当前工程源码、构建产物或模拟器操作能够核对的内容;出现“设计”“后续”“可以”时,指的是还需要继续编码、构建和验证的方案。两种语气必须分开。尤其是文件选择器、签名发布、动态主题和自动化 UI 测试等能力,不能因为路线图中有对应编号,就默认它们已经存在。

实现或设计步骤

第一步:定义状态边界

先确认哪些状态可以由一个源数据推导。当前页面使用 filterTodos() 生成可见任务,countRemaining() 生成未完成数量;编辑和删除则按稳定 id 定位对象。若本篇能力属于下一阶段设计,也要先说明它将新增什么状态、哪些状态不应该保存,避免功能完成后再次出现重复数据。

第二步:确定动作入口

用户动作应有一个明确入口。输入框提交进入 submitTodo(),复选框进入 toggleTodo(),卡片编辑和删除进入对应方法,持久化统一由 persistTodos() 负责。复杂功能可以继续拆分,但不要让同一类动作从多个组件直接改数组。统一入口能让错误提示、持久化和测试都有稳定落点。

第三步:让 UI 结果从状态产生

ArkUI 页面不需要在每个点击回调里手工刷新列表。只要状态写入正确,build() 中的派生查询、计数、空状态和卡片样式会重新读取数据。对于弹窗、导入、迁移等尚未接入的能力,仍应沿用同一原则:临时草稿先独立存在,校验通过后一次性写入源数据。

第四步:处理异常与边界

正常路径只说明功能能走通,边界路径才说明它是否可靠。要测试空标题、无匹配结果、重复点击、删除后撤销、应用重启、损坏存储、窄窗口、长标题以及任务顺序变化。对于本文暂未实现的部分,应把边界写成验收条件,不能用一段示例代码替代实际结果。

第五步:留存可复核的证据

代码文件说明“怎么写”,构建日志说明“能否打包”,HAP 路径说明“产物在哪里”,设备操作和截图说明“是否真的启动并交互”。这四类证据互相补充但不能互相替代。任何一类没有完成,都应在文章里明确标注待验证。

关键代码或数据协议

@State private editingId: number = 0;
@State private newTitle: string = '';

private startEditing(item: TodoItem): void {
  this.editingId = item.id;
  this.newTitle = item.title;
}

private cancelEditing(): void {
  this.editingId = 0;
  this.newTitle = '';
}

// 保存时按 id 替换,其他字段保持原值
this.todos = replaceTodo(this.todos, { ...current, title });

这段示例的价值不在于直接复制,而在于它把本篇的边界固定下来:数据从哪里来、动作在哪里进入、结果如何产生、失败时保留什么。真正接入工程时,还要根据当前 ArkTS 版本、页面上下文和设备能力重新构建,不能只看代码片段就断言已经运行。

验证路径

分别在“全部”“进行中”“已完成”页签打开编辑;输入空白内容并保存;修改标题后取消;编辑一项后切换搜索条件。观察按钮文案、输入框内容和卡片标题是否始终对应同一个 id。

建议每次验证都记录四个字段:前置数据、用户动作、预期结果、实际证据。例如“有两条进行中任务—点击第一条删除—列表减少一条且出现撤销—布局树出现撤销按钮并截图”。这样的记录比“功能测试通过”更容易在文章、测试用例和发布前清单之间复用。

如果验证发生在模拟器上,还要写清设备和产物来源。当前工程曾通过 hdc 安装 unsigned HAP 并启动 com.huihui.harmony.pctodoEntryAbility;这能证明当前包在该模拟器环境中安装启动,但不能替代用户签名或公开发布。对于未执行的设备动作,继续保留待验证状态。

当前模拟器画面

在这里插入图片描述

这张图只对应本文标注的已验证场景;它不替代签名、发布链接或未实现功能的验证。

常见误区和取舍

把数组下标存为编辑目标会在新增或筛选后失效;保存时只创建 { id, title } 会丢失其余字段;取消后不清空输入会造成下一次编辑串值;允许同时编辑多条任务则需要额外的编辑会话模型。

另一个常见误区是把“代码看起来合理”当作“项目已经完成”。ArkUI 组件参数、Preferences 上下文、窗口尺寸和设备签名都可能让理论代码在真实链路中出现差异。更稳妥的方式是先做小范围改动,运行静态构建,再在模拟器中按一条路径核验;一旦发现问题,记录首个明确错误,不要同时改动数据、布局和配置。

在性能、架构和功能之间也要做阶段性取舍。当前项目选择单页、纯函数和页面状态,是为了先把闭环跑通;当第二个页面、复杂数据源或多步历史真正出现时,再引入 Store、组件接口和版本迁移。架构不是越早越多越好,而是要在实际复杂度到来时提供清晰边界。

后续工作

当前实现适合轻量标题编辑。后续若要编辑分类、时间和优先级,应把顶部字符串升级成 TodoDraft,并复用新建任务的校验流程,而不是为每个字段增加一组独立状态。

无论下一步选择哪一项,都应先把它拆成最小可验证增量:先增加模型或工具函数,再接入页面,再执行构建,最后补设备操作和文章证据。这样后续文章才会自然形成开发记录,而不是提前写好的功能承诺。

小结

本篇围绕“鸿蒙ArkUI实战:实现任务编辑并避免输入状态串扰”讨论的不是一个孤立控件,而是一条从用户问题到工程证据的完整路径。当前已实现的部分可以直接在待办项目中复查;尚未实现的部分则给出了状态边界、代码入口和验收条件。保持这种区分,文章才真正有助于读者复现,也能让项目后续进度保持可信。

发布前复查清单

把本文用于发布前,至少再做一次从源码到设备的交叉核对。先打开当前工程对应的文件,确认文章中的方法名、字段名、资源名和路径没有脱离实际代码;如果代码来自设计方案,就在段落中明确“待实现”,不要让读者误以为复制后即可得到同样结果。再检查文章里的动作顺序,确保每一个按钮、输入框和状态变化都有对应的前置条件和可观察结果。

第二步是核对边界。标题为空、搜索没有结果、任务已经完成、任务刚刚删除、存储值损坏、窗口宽度不足,这些情况至少要有一种明确处理方式。没有覆盖的边界不需要硬写成成功,但应该写出下一步验证方法。真实项目的可信度,往往来自对“不确定”的准确标注,而不是来自一句笼统的“功能完善”。

第三步是核对证据。静态检查、ArkTS 编译、HAP 生成、签名、安装、启动和交互属于不同层级;截图、布局树和日志也各自证明不同事情。将截图文件名、构建产物路径和操作步骤放在一起,读者才能知道这张图是在什么条件下得到的。若当前没有签名包或公开链接,文章应保持草稿状态,不要提前填写日期和地址。

最后回到文章本身:开头是否从具体问题进入,代码后是否解释了为什么这样写,取舍是否和当前项目规模匹配,结尾是否给出读者可以执行的复查步骤。这样的文章即使后续还会继续迭代,也不会因为一个未完成能力而失去整体可信度。

复现记录模板

读者可以把本篇内容整理成一张小表再开始操作。第一列写“准备条件”,包括工程根目录、目标 SDK、模拟器或真机状态;第二列写“动作”,例如输入、点击、重启、切换筛选或导入文件;第三列写“预期”,说明列表、提示、计数、输入框和持久化应该怎样变化;第四列写“实际证据”,填写日志、截图、布局树或测试结果。只有四列都能对应上,问题才容易复现和回退。

如果实际结果与预期不同,先保留失败现场,不要马上清空数据或覆盖截图。记录当时的筛选条件、任务数量、页面窗口、构建产物和第一条错误信息,再一次只改变一个变量。对于 ArkUI 页面,优先判断源数据是否正确、派生查询是否正确、组件是否收到新状态、布局是否把内容裁切;对于持久化问题,先判断读取失败、解析失败还是保存没有 flush。这样的排查顺序同样适用于读者自己的项目。

当本篇能力正式接入后,再回头把“设计/后续”措辞改为“已实现/已验证”,并补充新的截图和测试。不要只修改文章结论而不更新代码路径、registry 状态和问答。内容、工程和证据三者一起变化,发布记录才不会出现前后矛盾。

还要注意文章代码和项目代码的关系。文章中的片段可以为了讲解省略上下文,但必须注明它依赖的类型、资源或页面状态;如果片段只用于说明未来设计,就不应让读者误以为它能直接粘贴编译。发布前最好从文章中的每个路径和方法名反查一次工程,遇到已重命名的字段及时同步,避免读者按文章操作时卡在第一步。

对于已经验证的功能,最好同时保留成功和失败边界。比如持久化不仅要写“重启后仍在”,还要说明空存储、损坏 JSON 和保存异常怎么处理;响应式布局不仅要写“适配窄屏”,还要记录输入框、按钮和列表在窄窗口中是否仍可见。把这些边界写清楚,文章长度增加的同时也增加了可复用价值,而不是重复描述同一个结论。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐