我喜欢在现有的 Rails 应用程序中使用 Turbo Frames。
index.view 现在看起来是这样的:
<h1>Projects List</h1>
<div><strong><%= pluralize(@projects.size, "Project") %> currently</strong></div>
<table class="table">
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Description</th>
<th colspan="2" scope="col"></th>
</tr>
</thead>
<% @projects.each do |project| %>
<tr>
<td>
<%= link_to project.title, project %>
</td>
<td>
<%= project.description.truncate(40) %>
</td>
<td>
<%= link_to "Show", project, class: "link-info" %>
</td>
<td>
<%= turbo_frame_tag "edit_curr_project" do %>
<div>
<%= link_to "Edit", edit_project_path(project), class: "link-warning" %>
</div>
<% end %>
</td>
</tr>
<% end %>
</table>
<turbo-frame id="edit_curr_project">
<h1>Edit Project</h1>
<%= render "form", project: @project %>
</turbo-frame>
控制器类:
class ProjectsController < ApplicationController
before_action :authenticate_user!
before_action :set_project, only: [:show, :destroy, :edit, :update]
def index
@projects = Project.all
end
def show
end
def new
@project = Project.new
end
def create
@project = Project.new(project_params)
if @project.save
redirect_to @project, notice: "Project created successfully"
else
render :new, status: :unprocessable_entity
end
end
def edit
end
def update
if @project.update(project_params)
redirect_to @project, notice: "Project updated successfully"
else
render :edit, status: :unprocessable_entity
end
end
def destroy
@project.destroy
redirect_to root_path, notice: "Project has become removed"
end
private
def project_params
params.require(:project).permit(:title, :description)
end
def set_project
@project = Project.find(params[:id])
end
end
表格(更新前):
随后出现错误消息:
到目前为止,它有效,实体已更新。但是索引视图中显示“内容丢失”,我需要重新加载浏览器才能查看最近的更新?
我做错了什么?
如何解决这个问题,以便视图更新?
在实现 Turbo 框架时,您应该使用部分,因为当您单击链接或在 Turbo 框架内提交表单时,它会查找相同的框架 ID。例如, _comment.html.erb 部分
<%= turbo_frame_tag dom_id(comment) do %>
<div class="rounded-lg shadow-sm p-4 mb-4">
<div class="flex items-start">
<% if comment.user.avatar.attached? %>
<%= image_tag comment.user.avatar, class: 'w-10 h-10 rounded-full mr-4' %>
<% end %>
<div>
<div class="flex items-center mb-1">
<strong class="text-gray-900"><%= comment.user.username %></strong>
<span class="text-gray-500 text-sm ml-2"><%= time_ago_in_words(comment.created_at) + " ago" %></span>
</div>
<p class="text-gray-800 mb-2"><%= comment.content %></p>
<div class="flex items-center space-x-4">
<% if comment.likes.exists?(user: current_user) %>
<%= button_to unlike_post_comment_path(comment.post, comment), method: :delete, remote: true, class: 'text-sm text-blue-500' do %>
<%= heroicon "hand-thumb-up", variant: :solid, options: { class: "h-5 w-5" } %>
<% end %>
<% else %>
<%= button_to like_post_comment_path(comment.post, comment), method: :post, remote: true, class: 'text-sm text-blue-500' do %>
<%= heroicon "hand-thumb-up", variant: :outline, options: { class: "h-5 w-5" } %>
<% end %>
<% end %>
<span class="text-sm text-gray-500"><%= pluralize(comment.likes.count, 'like') if comment.likes.count > 0 %></span>
<% if current_user == comment.user %>
<%= link_to "Edit", edit_post_comment_path(comment.post, comment), class: 'text-sm text-gray-500' %>
<%= button_to "Delete", [comment.post, comment], method: :delete, remote: true, data: { turbo_confirm: "Are you sure?" }, class: 'text-sm text-red-500' %>
<% end %>
</div>
</div>
</div>
</div>
<% end %>
在 _comment.html.erb 中,我们有 Turbo_frame_tag dom_id(comment),它使用唯一的 ID 呈现每个评论,以便我们稍后可以定位它。
当我们单击上面代码中的编辑按钮时,turbo 将查找另一个 Turbo 帧,其注释 ID 与我们单击编辑按钮的帧相同。所以在我的 edit.html.erb 文件中,我们有相同的 Turbo_frame_tag dom_id(@comment)
<%= turbo_frame_tag dom_id(@comment) do %>
<div class="max-w-3xl mx-auto px-4 bg-white rounded-lg shadow-md p-4">
<h2 class="text-l font-semibold mb-4">Edit Comment</h2>
<%= form_with(model: [@post, @comment], local: true, html: { class: "bg-white rounded-lg" }) do |form| %>
<% if @comment.errors.any? %>
<div id="error_explanation" class="mb-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative">
<ul>
<% @comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="mb-4">
<%= form.label :content, class: "block text-gray-700 font-semibold" %>
<%= form.text_area :content, class: "w-full px-3 py-2 border rounded-lg text-gray-700 focus:outline-none focus:border-blue-500", rows: 4 %>
</div>
<div class="flex justify-end space-x-4">
<%= form.submit "Update Comment", class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded cursor-pointer" %>
</div>
<% end %>
</div>
<% end %>
因此,当我们单击编辑按钮时,_comment.html.erb 被替换为 edit.html.erb 当我们提交此表单时,编辑表单将再次被 _comment.html.erb 替换,因为我们正在使用该部分来显示评论。这样,我们就可以处理内联注释编辑,而无需任何页面刷新或 JS。