鸿蒙端行程表单:类型点击无反应(@Builder 值传参不刷新)、出行方式改平铺、参与人显示已选头像 #50

Open
opened 2026-11-05 02:57:04 +00:00 by laoyang · 0 comments
Owner

鸿蒙端行程表单:类型点击无反应、出行方式改平铺、参与人显示已选头像

用户反馈(2026-11-05)

① 类型点了没反应

「鸿蒙端行程类型还是不能点击,游玩、用餐、赶路、住宿、其他都不能点,点了没反应。」

根因(关键):@Builder 按值传参不建立依赖关系。

// ❌ 原来的写法
chip(label: string, on: boolean, onTap: () => void) {
  Text(label).backgroundColor(on ? accent : inputBg)
}
// 调用:this.chip(o.label, this.nodeType === o.key, ...)
//                    ↑ 传的是求值后的 boolean 字面量

ArkUI 的 @Builder 参数是值传递,不会与 @Local nodeType 建立依赖。
nodeType 变了,chip 的 UI 不重新计算 ⇒ 界面不刷新 ⇒ 看起来"点了没反应"。

⚠️ 这个坑特别容易误判:状态确实改了、保存也确实生效,
只是界面没更新,所以现象是"点不动"而不是"数据没存上"。

修法:不在参数里传求值结果,builder 内部直接读 this.xxx:

@Builder
chipType(o: FbNodeTypeOpt) {
  Text(o.icon + ' ' + o.label)
    .backgroundColor(this.nodeType === o.key ? this.accent : FbColors.inputBg)
    .onClick(() => { this.nodeType = o.key; })   // 直接改状态
}

同一问题也在 travelMode(出行方式)和 vehicleId(车辆)上,一并修。

② 出行方式横滑看不出来

「如果只是左右滑动,会给人一种感觉,好像它看不出来是可以左右滑动的。
你看我现在选的火车,火车在很靠后的位置,感觉像是空的。
这里面显示出来的是步行、骑行、自驾,后面的这些划过去才知道。
我现在是知道它有这些出行方式,但是不知道的人,他都不知道往右、往左滑。
所以我的建议也跟类型一样,这个平铺下来就可以了。」

修法:11 项全部平铺换行(约 3 行),一项不缺、不用猜能不能滑。

⚠️ 这推翻了之前"项数 >6 用横滑"的规则 —— 横滑的可发现性太差,
宁可多占两行也要让用户看见全部选项。

③ 参与的人看不到是谁

「如果这里已经选中了一个人,就在"参与的人"里面先把这个人显示出来。
底下再显示"已选一人,点此修改"。在"点此修改"上面,
把已经选中的这个人的头像和名字显示在这个按钮上面。
这样就更清楚了,我可以知道要不要改,是吧?
因为我现在都不知道有什么人,怎么知道要不要改他呢?」

修法:结构分两层

参与的人
┌─────────────────────┐
│ (头像) 红围脖    ✕  │  ← 已选的人,点头像可移除
└─────────────────────┘
[ 已选 1 人,点此修改 ]     ← 操作按钮

验收

  • 类型 5 项(游玩/用餐/赶路/住宿/其他)点击后立即变色,选中态可见
  • 出行方式 11 项全部平铺可见,无需左右滑动
  • 车辆则也平铺(若有车)
  • 参与的人:已选的人显示头像 + 名字
  • 参与的人:按钮文字是「已选 N 人,点此修改」
  • 点头像可以从选择里移除该人
  • 保存后重新打开,选中态仍然正确(证明状态真的存上了)

ArkTS 规范核对

规则 本改动
不跨 V1/V2 混用 ✅ 全程 @ComponentV2 + @Local
@Builder 返回 void,不可链式 ✅
ForEach 必须显式 key ✅ 每个都有 nt_ / tm_ / veh_ / pk_ 前缀
成员名不与链式属性重名 ✅ nodeType / travelMode / vehicleId 都是业务前缀

为什么单独建单

#47 修的是「类型划不动」(布局问题),本单是「能看见但点了没反应」(状态刷新问题,根因是 @Builder 值传参)。#48 改的是状态流转逻辑,与本单的表单交互无关。

# 鸿蒙端行程表单:类型点击无反应、出行方式改平铺、参与人显示已选头像 ## 用户反馈(2026-11-05) ### ① 类型点了没反应 > 「鸿蒙端行程类型还是不能点击,游玩、用餐、赶路、住宿、其他都不能点,点了没反应。」 **根因(关键)**:`@Builder` 按值传参不建立依赖关系。 ```typescript // ❌ 原来的写法 chip(label: string, on: boolean, onTap: () => void) { Text(label).backgroundColor(on ? accent : inputBg) } // 调用:this.chip(o.label, this.nodeType === o.key, ...) // ↑ 传的是求值后的 boolean 字面量 ``` ArkUI 的 `@Builder` 参数是**值传递**,不会与 `@Local nodeType` 建立依赖。 `nodeType` 变了,chip 的 UI **不重新计算** ⇒ 界面不刷新 ⇒ 看起来"点了没反应"。 ⚠️ 这个坑特别容易误判:状态**确实改了**、保存**也确实生效**, 只是界面没更新,所以现象是"点不动"而不是"数据没存上"。 **修法**:不在参数里传求值结果,builder 内部**直接读 `this.xxx`**: ```typescript @Builder chipType(o: FbNodeTypeOpt) { Text(o.icon + ' ' + o.label) .backgroundColor(this.nodeType === o.key ? this.accent : FbColors.inputBg) .onClick(() => { this.nodeType = o.key; }) // 直接改状态 } ``` 同一问题也在 `travelMode`(出行方式)和 `vehicleId`(车辆)上,一并修。 ### ② 出行方式横滑看不出来 > 「如果只是左右滑动,会给人一种感觉,好像它看不出来是可以左右滑动的。 > 你看我现在选的火车,火车在很靠后的位置,感觉像是空的。 > 这里面显示出来的是步行、骑行、自驾,后面的这些划过去才知道。 > 我现在是知道它有这些出行方式,但是不知道的人,他都不知道往右、往左滑。 > 所以我的建议也跟类型一样,这个平铺下来就可以了。」 **修法**:11 项全部**平铺换行**(约 3 行),一项不缺、不用猜能不能滑。 ⚠️ 这推翻了之前"项数 >6 用横滑"的规则 —— 横滑的**可发现性太差**, 宁可多占两行也要让用户看见全部选项。 ### ③ 参与的人看不到是谁 > 「如果这里已经选中了一个人,就在"参与的人"里面先把这个人显示出来。 > 底下再显示"已选一人,点此修改"。在"点此修改"上面, > 把已经选中的这个人的头像和名字显示在这个按钮上面。 > 这样就更清楚了,我可以知道要不要改,是吧? > 因为我现在都不知道有什么人,怎么知道要不要改他呢?」 **修法**:结构分两层 ``` 参与的人 ┌─────────────────────┐ │ (头像) 红围脖 ✕ │ ← 已选的人,点头像可移除 └─────────────────────┘ [ 已选 1 人,点此修改 ] ← 操作按钮 ``` ## 验收 - [ ] 类型 5 项(游玩/用餐/赶路/住宿/其他)点击后**立即变色**,选中态可见 - [ ] 出行方式 11 项全部平铺可见,无需左右滑动 - [ ] 车辆则也平铺(若有车) - [ ] 参与的人:已选的人显示**头像 + 名字** - [ ] 参与的人:按钮文字是「已选 N 人,点此修改」 - [ ] 点头像可以从选择里移除该人 - [ ] 保存后重新打开,选中态仍然正确(证明状态真的存上了) ## ArkTS 规范核对 | 规则 | 本改动 | |---|---| | 不跨 V1/V2 混用 | ✅ 全程 `@ComponentV2` + `@Local` | | `@Builder` 返回 void,不可链式 | ✅ | | `ForEach` 必须显式 key | ✅ 每个都有 `nt_` / `tm_` / `veh_` / `pk_` 前缀 | | 成员名不与链式属性重名 | ✅ `nodeType` / `travelMode` / `vehicleId` 都是业务前缀 | --- ### 为什么单独建单 #47 修的是「类型划不动」(布局问题),本单是「能看见但点了没反应」(状态刷新问题,根因是 @Builder 值传参)。#48 改的是状态流转逻辑,与本单的表单交互无关。
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: laoyang/FamilyBook#50