示例:待办事项
列表、文本输入和数组状态。源码:examples/todo。
qorm run examples/todo
输入一项任务并添加;切换任务的完成状态。列表与状态中的一个数组进行数据绑定, 因此添加/切换会使其重新渲染。
组成部分
一个与状态双向绑定的输入框,以及一个调用动作的添加按钮:
{ "type": "input", "id": "field", "binding": "inputValue", "placeholder": "New task…" }
{ "type": "button", "id": "add", "label": "Add",
"onPress": { "type": "invoke", "name": "addTodo", "args": { "text": "{{state.inputValue}}" } } }
添加动作将一个对象追加到数组中并清空输入框 (actions/addTodo.json):
{ "type": "action", "id": "addTodo", "steps": [
{ "type": "state.appendObject", "path": "items",
"item": { "id": "{{ text }}", "text": "{{ text }}", "done": "{{ false }}" } },
{ "type": "state.set", "path": "inputValue", "value": "" }
] }
一个数据绑定的列表渲染每一项;{{item.*}} 是每行的作用域:
{ "type": "list", "id": "items", "data": "{{ state.items }}",
"renderItem": { "type": "row", "children": [
{ "type": "checkbox", "onChange": { "type": "invoke", "name": "toggleTodo", "args": { "id": "{{item.id}}" } } },
{ "type": "text", "text": "{{ item.text }}" }
] } }
行模板还能看到自己的位置——{{ index }}(从 0 开始),以及 first 与 last 两个标志——因此序号、斑马纹、"最后一行不画分隔线"都不需要额外的状态:
{ "type": "list", "id": "items", "data": "{{ state.items }}", "separator": true,
"renderItem": { "type": "row", "children": [
{ "type": "text", "text": "{{ index + 1 }}." },
{ "type": "text", "text": "{{ item.text }}" }
] } }
一行统计信息就是同一个数组上的一个表达式:
{ "type": "text", "text": "{{ count(state.items, \"it.done\") }} of {{ len(state.items) }} done" }
格式说明
- 重复渲染使用
list,配合data: "{{ state.items }}"和一个renderItem
模板(而非 item);{{ item.* }} 仅在该模板内部可见。
- 使用
state.appendObject追加;通过binding实现双向输入。 index/first/last是独立的作用域名字,所以你自己数据里的index
字段永远不会被遮蔽。
- 更长的列表可以用
separator、pageSize+page、groupBy与
onRefresh——见第一个场景。