Rails Turbo Frames:更新操作后“内容丢失”(视图不更新)

问题描述 投票:0回答:1

我喜欢在现有的 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

表格(更新前):

Edit-form

随后出现错误消息:

Error-message

到目前为止,它有效,实体已更新。但是索引视图中显示“内容丢失”,我需要重新加载浏览器才能查看最近的更新?

我做错了什么?

如何解决这个问题,以便视图更新?

ruby-on-rails ruby hotwire-rails turbo-rails
1个回答
0
投票

在实现 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。

© www.soinside.com 2019 - 2024. All rights reserved.