ArkTS UI 备忘
一个状态更新未引起UI重绘的问题
案例是一个ToDo List的应用, 先定义一个模型, 状态变更主要是它:
@Observed
class TodoItem {
id: string = ''
text: string = ''
completed: boolean = false
editMode: boolean = false
finishTime: string = ''
}
再定义基本UI:
@Component
struct TodoListItem {
@ObjectLink item: TodoItem
build() {
Row() {
// 复选框
Toggle({type: ToggleType.Checkbox, isOn: this.item.completed})
// Checkbox().select(this.item.completed) // select方法可能会触发事件, 改用Toggle
.onChange((isOn: boolean) => {
console.log(`${this.item.text}, ${isOn}`)
this.item.completed = isOn
this.item.finishTime = isOn ? new Date().toLocaleString() : ''
})
... // 略
页面:
@Entry
@Component
struct TodoList {
@State todos: TodoItem[] = [
{ id: '1', text: '学习ArkUI', completed: false, editMode: false, finishTime: '' },
{ id: '2', text: '开发TODO应用', completed: true, editMode: false, finishTime: '2025-10-21 13:17:22' },
{ id: '3', text: '测试滑动删除', completed: false, editMode: false, finishTime: '' }
]
build() {
Column() {
ForEach(this.items, (item: TodoItem) => {
TodoListItem({item})
})
}
}
}
在Entry里通过Foreach送入, 代码略, 运行后, 发现点击复选框, 状态变更了, 但是UI没有更新. 跟AI PK了一天, 发现是数据源用了字面量来初始化TodoListItem对象(测试即使加as ToDoItem也不行), 导致状态变更后, UI没有重绘. 修改为new TodoListItem()后, 问题解决.
constructor(id: string, text: string, completed?: boolean, editMode?: boolean, finishTime?: string) {
this.id = id;
this.text = text;
this.completed = completed || false;
this.editMode = editMode || false;
this.finishTime = finishTime || '';
}
这个一定要记录一下, 巨坑, 用字面量本为了省个构造函数, 结果不但需要重复写字面量, 还导致状态监控链条打破了.