按钮只报一个名字 — 按下去时宿主做了什么
5 分钟目标画面课程第 4 讲。onTap 里没有代码,只有工具名。那个名字是否真的到了宿主,图上看不出来,所以测试台亲自按下去并记下来。
第 3 讲把值送进了画面。反方向还没讲。
onTap 里没有代码
{ "type": "button", "label": "Call next", "onTap": { "type": "tool", "tool": "queue.next" } },
{ "type": "button", "label": "Take a ticket", "onTap": { "type": "tool", "tool": "queue.take" } }onTap 是 { type, tool }。「按这个会调用一个叫 queue.next 的工具」就是全部,那工具做什么并没有写。
也写不了。这个文件是服务器课程里做的那台服务器发来的,活儿在那台服务器上干。
接住的一侧
rt.buildUI(
context: c,
// 名字到这儿。宿主不知道这名字是什么意思。
onToolCall: (tool, params) async => fired.add(tool),
)这就是第 1 讲留成空函数的那个位置。在真实应用里,这里放的是客户端课程第 3 讲的一行。
onToolCall: (tool, params) async {
// 名字来自画面。原样传过去。
final r = await client.callTool(tool, params);
final state = jsonDecode((r.content.first as TextContent).text)
as Map<String, dynamic>;
state.forEach(rt.stateManager.set);
},tool 原样传过去。没有 if (tool == 'queue.next') 这样的分支 — 一旦加进去,服务器每多一个工具就得改一次宿主。
图上定不了这件事
到这里截图第一次不够用了。step4.png 上看得见两个按钮。看不见的是 它们被按下时会发出什么。
把 onTap 整个删掉,图还是一模一样。
所以测试台亲自按。
fired.clear();
await tester.tap(find.text('Call next'));
await tester.pump(const Duration(milliseconds: 40));
await tester.tap(find.text('Take a ticket'));
await tester.pump(const Duration(milliseconds: 40));
say('pressed -> the host was asked for: ${fired.join(", ")}');pressed -> the host was asked for: queue.next, queue.takefired 是 onToolCall 按顺序接到的名字。这一行落进 run.log,检查再把它读回来。
# 宿主若知道工具名,就失败
grep -rq 'queue\.next\|queue\.take' $SRC && \
die "step4: the host knows the tool names"
# 按下去后,画面要求的名字没到,就失败
grep -q 'the host was asked for: queue.next, queue.take' $LOG || \
die "step4: pressing did not send the tool names the screen asked for"两行放在一起才有意义。只有上面一行,说的是「名字不在宿主里」;只有下面一行,名字写死在宿主里也照样通过。叠起来才是 画面给的名字原样发了出去。
删掉 onTap 再跑,下面那行会抓住。
[5/8] step4 — the button names a tool and stops there
step4: pressing did not send the tool names the screen asked for失败不在画面上处理
queue.next 被拒了会怎样?服务器课程第 3 讲的叫号器,在没人等的时候会拒绝叫号。
拒绝也是结果。服务器返回 isError 和理由,它和别的值一起作为状态进来。
{ "type": "text", "text": "{{notice}}", "style": { "fontSize": 15, "color": "#9ca3af" } }step4.json 靠下的这一行就是那个位置。画面定义里没有单独的错误处理语法 — 理由也不过是状态里的一个值。
渲染
step4 896 B, 12 lines, type "page" -> step4.png43,下面 2 waiting,两个按钮,再下面灰色的 called 43。
自己跑一遍
cd content/sample/course-ui
bash verify.sh
cat captures/run.log带走的
onTap: { type: 'tool', tool: ... }— 画面只知道名字,到此为止onToolCall原样传 — 不要按名字分支- 会按下去的检查 — 截图看不见的,就写进日志
下一讲
最后一讲。一个画面变成两种形状 — 以及一个不知道自己有多长的列表。
运行示例
makemind-academy/course_ui/git clone https://github.com/makemind-academy/course_ui cd course_ui bash verify.sh