关于 hotwire-coder
用于在 Rails 应用中构建 Hotwire 功能的开发 Skill,涵盖 Turbo Drive、Frames、Streams、实时广播和常见界面模式,并说明实现内容的组织方式。
主要功能
- 01Turbo Drive 导航
- 02Turbo Frames 局部更新
- 03Turbo Streams 与广播
- 04模态框和无限滚动模式
- 05调试及反模式指导
适用场景
- 01添加页面局部更新
- 02构建实时评论视图
- 03实现模态框或无限滚动界面
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill hotwire-coder安装后在 Claude Code 中输入/hotwire-coder确认已加载。
附带文件references/lazy-loading.md
详细介绍
Hotwire 编码者
Hotwire 理念
Hotwire 通过网络传输 HTML,而不是 JSON:
- Turbo Drive - 通过替换
<body>加快导航,无需完整重新加载页面 - Turbo Frames - 将页面拆分为独立上下文,并按请求更新
- Turbo Streams - 从服务端发送页面局部更新(HTTP 或 WebSocket)
Turbo Drive
选择性退出
<%= link_to "Download PDF", report_path(format: :pdf), data: { turbo: false } %>
<%= form_with model: @legacy, data: { turbo: false } do |f| %>
表单提交
def create
@post = Post.new(post_params)
@post.save ? redirect_to(@post, notice: "Created!") : render(:new, status: :unprocessable_entity)
end
Turbo Frames
基本 Frame
<turbo-frame id="comments">
<%= render @post.comments %>
<%= link_to "Load More", post_comments_path(@post, page: 2) %>
</turbo-frame>
延迟加载
<turbo-frame id="notifications" src="<%= notifications_path %>" loading="lazy">
<p>Loading...</p>
</turbo-frame>
有关骨架 UI 模式、无限滚动和 Stimulus 加载控制器,请参阅 references/lazy-loading.md。
跳出 Frame
<%= link_to "View Post", post_path(@post), data: { turbo_frame: "_top" } %>
<%= link_to "Results", search_path, data: { turbo_frame: "results" } %>
行内编辑模式
<turbo-frame id="<%= dom_id(post) %>">
<article>
<h2><%= post.title %></h2>
<%= link_to "Edit", edit_post_path(post) %>
</article>
</turbo-frame>
Turbo Streams
Stream 操作
<%= turbo_stream.append "comments" do %><%= render @comment %><% end %>
<%= turbo_stream.replace dom_id(@post) do %><%= render @post %><% end %>
<%= turbo_stream.remove dom_id(@comment) %>
HTTP Stream 响应
def create
@comment = @post.comments.create(comment_params)
respond_to do |format|
format.turbo_stream # renders create.turbo_stream.erb
format.html { redirect_to @post }
end
end
实时广播
class Comment < ApplicationRecord
after_create_commit -> {
broadcast_append_to post, target: "comments", partial: "comments/comment"
}
after_update_commit -> { broadcast_replace_to post }
after_destroy_commit -> { broadcast_remove_to post }
end
<%= turbo_stream_from @post %>
<div id="comments"><%= render @post.comments %></div>
注意: 对于大模型流式传输或需要保证消息送达的功能,请参阅
anycable-coder技能。Action Cable 提供至多一次送达保证,重新连接时可能会丢失数据块。
Turbo 8 变形
<head>
<meta name="turbo-refresh-method" content="morph">
<meta name="turbo-refresh-scroll" content="preserve">
</head>
class Post < ApplicationRecord
after_update_commit -> { broadcast_refresh_to self }
end
常见模式
模态框模式
<%= link_to "New Post", new_post_path, data: { turbo_frame: "modal" } %>
<turbo-frame id="modal"></turbo-frame>
无限滚动
<div id="posts"><%= render @posts %></div>
<% if @posts.next_page? %>
<turbo-frame id="pagination" src="<%= posts_path(page: @posts.next_page) %>" loading="lazy">
<p>Loading more...</p>
</turbo-frame>
<% end %>
反模式
| 反模式 | 问题 | 解决方案 |
|---|---|---|
| Frame ID 不匹配 | 静默失败 | 验证 ID 是否匹配 |
| 缺少状态码 | Turbo 忽略响应 | 正确使用 422/303 |
| 广播中使用隐式局部变量 | 运行时错误 | 始终传入 request_id: nil |
调试
Turbo.setDebug(true)
document.addEventListener("turbo:frame-missing", (e) => console.error("Frame not found:", e.detail.response))
输出格式
实现 Hotwire 功能时,请提供:
- 控制器 - 带有正确响应处理的操作
- 视图 - 包含 frames 和 streams 的 HTML/ERB
- 模型 - 如需实时功能,则包含广播回调
- JavaScript - 如需使用,则包含 Stimulus 控制器
评论
支持 Markdown