市集表单内核(第2篇):HarmonyOS 条件字段与失效输入回收【共创稿事节】
市集摊位中的经营类别与用电需求联动里有一个看似不起眼的约束:经营类别从热食改成文创后,用电功率字段虽然隐藏,旧值却被提交到后台。如果直接给事件回调增加更多条件,短期可能看起来好用,却会让下一次需求变更更加困难。

业务行为与实现目标
依赖字段的问题有时很隐蔽。申请人先选择热食并填写两千瓦,再改成只售手工饰品;界面因为显隐规则收起功率输入,但序列化程序仍可能把两千瓦原样发送。服务端看到的申请与用户最终确认的页面不一致,这是数据一致性问题。
“可见性是规则结果,不是值合法性的证据;隐藏字段的有效值必须显式处理”是这篇最重要的设计判断。单看成功路径,市集摊位中的经营类别与用电需求联动可以靠若干事件回调工作;但只要用户中途修改、取消或重复操作,若没有清晰约束,就无法确定最终输出究竟属于哪一次输入。工程拆分必须以这些不确定性为起点。
我们希望得到的不是一张孤立的效果图,而是一条可追溯的处理链。整个过程拆为选择变动、依赖求值、可见集变化、回收旧值、重新校验。每一段只承诺自己负责的结果,下一段不靠猜测前一步的内部状态。对条件依赖而言,这种清晰分工也是回归测试能够写得具体的前提。
显隐的推导应是一个纯函数:给相同的 category、needPower,总能算出相同结果。不要把它藏在多个 onChange 回调里,因为回调执行顺序并不等于业务规则优先级,更不利于用例覆盖所有组合。
把决策拆进最小单元
实施选择是:用 pure function 计算字段依赖,按显隐变化执行归零或保留草稿两种清晰策略。这里不能倒过来,先把组件和请求写完,再向现有代码里硬塞判断。规则入口只接收必要数据,输出也尽量可序列化。这样在没有设备的环境下仍能对核心逻辑做确定性检查。
把“选择变动”到“依赖求值”视作可中断的边界。任何阶段都可能遇到无效输入或设备状态变化,恢复时应回到上一个仍然可信的事实,而不是为了显示流畅强行跳到最终步骤。这样的路径更适合实际调试。
把“依赖求值”和“可见集变化”分成两个阶段,是为了让每个阶段都有可检查的输入与输出。市集摊位中的经营类别与用电需求联动并不需要复杂框架才能做到这一点,真正需要的是一个稳定的数据契约:前一步产出的值能被下一步清楚识别,失败时也能停在正确的位置。
从“可见集变化”走到“回收旧值”时,不要直接复用页面当前显示的全部状态。界面可能正在更新,用户也可能继续操作。此处应只传递本阶段约定的数据,并记录这份数据属于哪次动作,减少跨阶段读到不同版本的风险。
清理旧值有两种合法策略:一是立即置空,二是临时保留供用户切回,但提交前始终过滤失效字段。对于用电功率这类会影响审批的值,我们选择立即清空,避免回切后不经确认继续使用旧功率。

逐行理解核心代码
下面给出可以独立检查的关键实现。代码只覆盖本篇要证明的核心行为;涉及工程权限、服务端协议或构建设置的条件已在上下文列明。它应被放入明确的模块中,而不是把所有业务逻辑堆进 ArkUI build()。
interface StallForm { category: string; needPower: boolean; watt: string }
function isWattVisible(s: StallForm): boolean {
return s.category === '热食' && s.needPower
}
function changeCategory(old: StallForm, category: string): StallForm {
const next: StallForm = { ...old, category: category }
if (!isWattVisible(next)) {
next.needPower = false
next.watt = ''
}
return next
}
function submitPayload(s: StallForm): StallForm {
return isWattVisible(s) ? { ...s } : { ...s, watt: '' }
}
条件逻辑变多以后,需要考虑依赖环。例如 A 可见取决于 B,B 又依赖 A,这会让规则无法稳定求值。实际实现可以定义有向依赖关系,在注册时做环检测;简单示例中依赖都由固定的经营类别出发,因此暂不存在环。
代码中的关键判断来自业务约束,而不是某个屏幕比例。以“可见集变化”为界,输入应先满足所属阶段的前置条件;当判断失败时,返回错误或保留状态比直接抛出无法解释的页面状态更可控。对需要 UI 反馈的部分,随后由组件转换为明确的文案。
如果把上述核心逻辑接到一个 ArkUI 页面,推荐组件仅处理状态投影和交互事件:例如 TextInput.onChange 接收新的字符串,Button.onClick 触发一次显式动作,得到结果后再设置 @State 驱动展示。对于不是输入框的条件依赖功能,则采用相同的单向数据边界而不强行引入 TextInput。

问题分支和异常路径
最应该提前考虑的风险是:同一字段被多条规则控制时应统一合成,避免最后一条规则随遍历顺序覆盖前面的结果。这句话不是发布时随手附加的注意事项,而是编码时必须坚持的限制。只要异常路径缺乏明确处理,下一次回归就可能把一个本来可恢复的状态变成难以判断的失败。
测试使用热食→文创→热食三步,重点不是最后看到几个输入框,而是三步中序列化的 watt 是否符合业务约束。还应测试“无需电源”时 power=false 和 watt 空值在服务器端的解释是否一致。
跨版本核对。 在数据和配置持续演进的前提下,固定一份输入,记录预期输出;随后修改不相关的界面颜色或布局,再运行同一用例。如果结果变化,说明条件依赖与展示层之间出现了不应存在的隐性耦合。
边界值核对。 不只输入一个“正常例子”,还需要空字符串、用户明确的否定值、最大长度附近以及重复内容等不同形态。对条件依赖来说,边界值是否被恰当表达,往往比用户第一次成功完成流程更能反映实现质量。
状态验收。 在市集摊位中的经营类别与用电需求联动中,专门制造一个尚未完成的状态:经营类别从热食改成文创后,用电功率字段虽然隐藏,旧值却被提交到后台。观察模块是否明确阻止下一动作、是否保留用户已经输入的有效内容,以及重新操作后是否会得到可解释的新结果。这个检查的价值在于不把一次成功操作当作稳定性的全部证据。
逆序验收。 把正常操作反过来执行,例如先触发选择变动,再补齐选择变动所需要的条件。若界面没有把错误留在错误位置,或者隐式使用上一轮结果,就说明阶段约束并未完全落实。真正的测试应覆盖操作顺序变化,而非只按产品示例步骤点击。
围绕行为做回归
后续跨字段校验可以直接调用 isWattVisible,而不必复制“类别等于热食并且需要电源”的条件表达式。规则只有一个来源,才能避免显隐与校验在日后独立演化。
本篇可用以下结果作为验收目标:热食→文创→热食的切换不会悄悄恢复上一次不适用的功率。检验时先从固定输入入手,再加入中途切换、重复操作和失败恢复。可解释的错误结果也属于正确实现的一部分;没有必要为了让每个步骤都显示绿色而悄悄跳过不满足的前置条件。
对于业务异常,提示文案至少要回答当前状态、可以继续的动作以及不能继续的原因。市集摊位中的经营类别与用电需求联动里的用户通常不关心内部类名或错误码,但需要知道是等待、重试还是修改输入。把工程错误类别映射为用户可理解的行为建议,比把原始异常堆栈放在对话框里更合适。
交付的验证证据应当与主张相称。纯函数逻辑可以使用固定输入输出来证明;界面效果只能由真实运行或明确标注的示意展示;网络限流、签名、权限等涉及外部系统的结论,需要在对应环境中完成复核。不要把静态检查结果提升为已经完成真实设备测试的结论。
还有一个容易被忽视的协作问题:页面状态、领域规则和最终输出往往由不同代码文件甚至不同开发者维护。要让改动可控,必须为条件依赖明确最小接口,规定哪些数据可以跨模块传递、哪些只是展示层的临时变量;代码评审只要看到两处重复决定同一事实,就需要回到单一来源原则。
调试不应从增加大量打印开始。先把选择变动 → 依赖求值 → 可见集变化 → 回收旧值 → 重新校验按顺序列出来,每次只在边界处记录不含个人信息的阶段与结果类别。这样即使没有真机性能指标,仍能通过构造输入与检查返回值定位哪一步发生分歧;反过来,如果只看最终页面颜色,就难以证明中间没有错误。
这类问题的适用边界同样清楚:可见性是规则结果,不是值合法性的证据;隐藏字段的有效值必须显式处理。当具体 SDK、设备能力或服务端协议发生变化,应重新查看对应的官方接口约束,再重新跑上述场景验证,而不是根据一张示例图推断系统行为。
官方资料
更多推荐

所有评论(0)