javascript - Rails 关联表单与 Ajax 更新

标签 javascript jquery ruby-on-rails ajax

我有一个模型,一本书,有一个 has_many 关联,拥有。我已将其设置为用户可以单击按钮将书籍添加到他们的收藏中。 Controller 看起来像这样:

def create
    @book.owns.where(user_id: current_user.id).first_or_create
    @own = Own.where(user_id: current_user.id, book_id: @book.id)
    Own.update(@own, :quantity => "1")
    respond_to do |format|
        format.html { redirect_to @book}
        format.js
    end
end

View 如下所示:

<% if user_signed_in? && current_user.owns?(@book) %>
    <%= link_to book_own_path(@book), method: :delete, remote: true, class: "btn btn-danger btn-circle", title: "Remove from collection", data: { toggle: "tooltip", disable_with: "<span class='fa fa-minus'></span>"} do %><span class="fa fa-heart-o"></span><% end %>
<% else %>
    <%= link_to book_own_path(@book), method: :post, remote: true, class: "btn btn-success btn-circle", title: "Add to collection", data: { toggle: "tooltip", disable_with: "<span class='fa fa-plus'></span>"} do %><span class="fa fa-heart"></span><% end %>
<% end %>

这样,当单击该按钮时,它会自动将数量 1 添加到其库存中。我想要做的是让用户能够从图书展示 View 中更新他们拥有的数量,所以我添加了以下内容:

<% if user_signed_in? && current_user.owns?(@book) %>
    <span id="<%= @book.id %>_quantity">
        <% Own.where(:user_id => current_user.id, :book_id => @book.id).each do |z| %>
        <% if z.quantity == 1 %>
            <form>
                You own <input type="text" placeholder="<%= z.quantity %>" id="quantity" name="quantity" size="1" class="text-center" /> copies of this book
                <input type="submit" onclick="<% Own.update(@own, :quantity => params[:quantity]) %>.submit();" hidden />
            <form>
        <% else %>
            <form>
                You own <input type="text" placeholder="<%= z.quantity %>" id="quantity" name="quantity" size="1" class="text-center" /> copies of this book
                <input type="submit" onclick="<% Own.update(@own, :quantity => params[:quantity]) %>.submit();" hidden />
            <form>
        <% end %>
    <% end %>
    <br />
    </span>
<% end %>

当我单击 Enter 时,上面的内容会更新自己的数量,但它会将我重定向到相同的网址,并在末尾添加 ?quantity=1 (或任何数量值)。除非刷新页面,否则它也不会在输入占位符中显示数量。

我的问题是,有没有更好的方法来解决这个问题,或者有没有办法实际显示占位符值。另外,如何在后台提交表单而不是刷新页面的情况下设置此设置?

最佳答案

要在 Rails 中构建表单,您应该使用 Rails 提供的内容: Rails doc for Form helpers

或者像 SimpleForm 这样的 gem

此示例假设您使用的是 Rails 4+。

首先,您想要显示您的书籍页面,因此加载您的书籍并加载您自己的书籍(当您操作模型时最好在 Controller 中执行此操作):

# Books Controller
def show
  @book = Book.find(params[:id])
  @owns = current_user.owns.where(book: @book)
end

你的观点现在可能是这样的:

# Book show
<% @owns.each do |own| %>
  <div> You own <span class="<%= own.id %>_quantity"><%= own.quantity %></span> of this book </div>
  <%= form_for own, remote: true, method: :put do |f| %>
    <%= f.hidden_field :quantity, value: own.quantity + 1 %>
    <%= f.submit "Add One" %>
  <% end %>
  <hr>
<% end %>

我们迭代我们自己的表单并创建一个将数量加 1 的表单。由于表单上的 PUT 方法,该请求将转到 Own#update。由于属性“remote: true”,表单将通过 AJAX 发送(这是在表单中使用 AJAX 的 Rails 方法之一:Rails doc for AJAX)。

# Own Controller
def update
  @own = Own.find(params[:id])
  respond_to do |format|
    if @own.update(own_params)
      format.html do
        redirect_to book_path(@own.book), notice: 'success'
      end
      format.js
    else
      format.html do
        redirect_to book_path(@own.book), alert: 'fail'
      end
    end
  end  
end

def own_params
  params.require(:own).permit(:quantity)
end

在这里,我们将加载我们自己的并尝试更新它。如果禁用 JS,请求将采用 HTML 部分并重定向到您想要的位置。如果启用了 JS,那么您可以创建一个“JS View ”,其呈现方式与 html View 完全相同(您必须以操作名称来命名它们)。所以,它可能是这样的:

# views/owns/update.js.erb
$(".<%= @own.id %>_quantity").html("<%= @own.quantity %>");

它将用新数量替换范围的内容。

我还没有测试过,但最后,你的代码可能是这样的

关于javascript - Rails 关联表单与 Ajax 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33466773/

相关文章:

jquery - 尝试设置从右侧滑入的 Jansy-bootstrap offcanvas 菜单

ruby-on-rails - 启动 irb 或脚本/控制台时未执行 ~/.irbrc

javascript - Node.js 与 Express : Change response data for certain path

javascript - 覆盖键/值数组中的键(如果存在)

javascript - 从数组的值创建数组

ios - Heroku:运行我的应用程序的成本有多高?

ruby-on-rails - 为什么我的 Rails 应用程序不获取服务器上错误消息的翻译

javascript - 如何获取克隆元素的outerHTML?

javascript - Html:在页面加载时加载方便的图像大小?

javascript - 如何自动更新复制的 fabricjs Canvas ?