Rails 嵌套的 Hotwire actioncable 流 turbo_frame_tag
Rails Hotwire actioncable stream in nested turbo_frame_tag
关注 an article 我正在尝试 Rails Hotwire 并希望创建一个像单页应用程序一样工作的简单博客(即使用 turbo_stream
来 crud posts 和评论而无需重新加载整个页面)。我还想通过为所有连接的浏览器实时执行 crud 操作来同时使用 actioncable。
到目前为止,除了当我显示特定的 post(即 posts/show
)时对 post 的评论的实时部分之外,它正在工作。
这可能与我用于 turbo_frame_tags
and/or 的标识符有关 broadcast
但我似乎找不到答案。
我查看了this question and also a GoRails example of something similar,但还是不行。
我现在的posts/index
<%= turbo_stream_from "posts" %>
<div class="w-full">
[...]
<div class="min-w-full">
<%= turbo_frame_tag :posts do %>
<%= render @posts %>
<% end %>
</div>
</div>
每个 post 的部分如下:
<%= turbo_frame_tag post do %>
<div class="bg-white w-full p-4 rounded-md mt-2">
<h1 class="my-5 text-lg font-bold text-gray-700 text-4xl hover:text-blue-400">
<%= link_to post.title, post_path(post) %>
</h1>
[...]
</div>
<% end %>
posts/show
将每个 post 的当前部分替换为更详细的版本:
<%= turbo_stream_from @post, :comments %>
<%= turbo_frame_tag dom_id(@post) do %>
[...]
<div class="w-full bg-white rounded-md p-4 justify-start mt-1">
<div class="w-full pt-2">
<turbo-frame id="total_comments" class="mt-2 text-lg text-2xl mt-2 tex-gray-50">
<%= @post.comments.size %> comments
</turbo-frame>
<%= turbo_frame_tag "#{dom_id(@post)}_comments" do %>
<%= render @post.comments %>
<% end %>
[...]
</div>
</div>
</div>
<% end %>
相应的模型是:
class Post < ApplicationRecord
validates_presence_of :title
has_rich_text :content
has_many :comments, dependent: :destroy
after_create_commit { broadcast_prepend_to "posts" }
after_update_commit { broadcast_replace_to "posts" }
after_destroy_commit { broadcast_remove_to "posts" }
end
和
class Comment < ApplicationRecord
include ActionView::RecordIdentifier
belongs_to :post
has_rich_text :content
after_create_commit do
broadcast_append_to [post, :comments], target: "#{dom_id(post)}_comments", partial: 'comments/comment'
end
after_destroy_commit do
broadcast_remove_to self
end
end
_comment
部分是
<%= turbo_frame_tag dom_id comment do %>
<div class="container w-full mx-auto bg-white p-4 rounded-md mt-2 border-b shadow">
<%= comment.content %> - <%= time_tag comment.created_at, "data-local": "time-ago" %>
[...]
</div>
<% end %>
如前所述,实时处理 post 的工作而不是他们的评论。知道我做错了什么吗?
提前致谢。
我找到了解决办法。只是将流放在哪里的问题:
在show
中,<%= turbo_stream_from @post, :comments %>
应该在<%= turbo_frame_tag dom_id(@post) do %>
之后。
而 _comment
部分应该像
<%= turbo_stream_from comment %>
<%= turbo_frame_tag dom_id comment do %>
[...content]
</div>
<% end %>
上面有更详细的解释
关注 an article 我正在尝试 Rails Hotwire 并希望创建一个像单页应用程序一样工作的简单博客(即使用 turbo_stream
来 crud posts 和评论而无需重新加载整个页面)。我还想通过为所有连接的浏览器实时执行 crud 操作来同时使用 actioncable。
到目前为止,除了当我显示特定的 post(即 posts/show
)时对 post 的评论的实时部分之外,它正在工作。
这可能与我用于 turbo_frame_tags
and/or 的标识符有关 broadcast
但我似乎找不到答案。
我查看了this question and also a GoRails example of something similar,但还是不行。
我现在的posts/index
<%= turbo_stream_from "posts" %>
<div class="w-full">
[...]
<div class="min-w-full">
<%= turbo_frame_tag :posts do %>
<%= render @posts %>
<% end %>
</div>
</div>
每个 post 的部分如下:
<%= turbo_frame_tag post do %>
<div class="bg-white w-full p-4 rounded-md mt-2">
<h1 class="my-5 text-lg font-bold text-gray-700 text-4xl hover:text-blue-400">
<%= link_to post.title, post_path(post) %>
</h1>
[...]
</div>
<% end %>
posts/show
将每个 post 的当前部分替换为更详细的版本:
<%= turbo_stream_from @post, :comments %>
<%= turbo_frame_tag dom_id(@post) do %>
[...]
<div class="w-full bg-white rounded-md p-4 justify-start mt-1">
<div class="w-full pt-2">
<turbo-frame id="total_comments" class="mt-2 text-lg text-2xl mt-2 tex-gray-50">
<%= @post.comments.size %> comments
</turbo-frame>
<%= turbo_frame_tag "#{dom_id(@post)}_comments" do %>
<%= render @post.comments %>
<% end %>
[...]
</div>
</div>
</div>
<% end %>
相应的模型是:
class Post < ApplicationRecord
validates_presence_of :title
has_rich_text :content
has_many :comments, dependent: :destroy
after_create_commit { broadcast_prepend_to "posts" }
after_update_commit { broadcast_replace_to "posts" }
after_destroy_commit { broadcast_remove_to "posts" }
end
和
class Comment < ApplicationRecord
include ActionView::RecordIdentifier
belongs_to :post
has_rich_text :content
after_create_commit do
broadcast_append_to [post, :comments], target: "#{dom_id(post)}_comments", partial: 'comments/comment'
end
after_destroy_commit do
broadcast_remove_to self
end
end
_comment
部分是
<%= turbo_frame_tag dom_id comment do %>
<div class="container w-full mx-auto bg-white p-4 rounded-md mt-2 border-b shadow">
<%= comment.content %> - <%= time_tag comment.created_at, "data-local": "time-ago" %>
[...]
</div>
<% end %>
如前所述,实时处理 post 的工作而不是他们的评论。知道我做错了什么吗? 提前致谢。
我找到了解决办法。只是将流放在哪里的问题:
在show
中,<%= turbo_stream_from @post, :comments %>
应该在<%= turbo_frame_tag dom_id(@post) do %>
之后。
而 _comment
部分应该像
<%= turbo_stream_from comment %>
<%= turbo_frame_tag dom_id comment do %>
[...content]
</div>
<% end %>
上面有更详细的解释