【问题标题】:Increment column in model with Ajax in ruby on rails在 ruby​​ on rails 中使用 Ajax 增加模型中的列
【发布时间】:2018-10-14 18:01:33
【问题描述】:

我是 Rails 新手,在我的 Rails 应用程序中为销售模型增加整数列(数量)时遇到问题。用户可以使用如下按钮在应用中增加产品的数量:

Sales/show.html.erb

 <tbody>
 <% @ven_pros.each {|s| %>
                  <tr>

                    <td><%= link_to ' + ', "/sale_products/#{params[:id]}/increment/#{s.id};", class: "btn btn-md btn-primary" %></td>

                  </tr>

                <% } %>
 </tbody>

这是我的路线

routes.rb

get   'sale_products/:id/increment/:product_id' , to: 'sale_products#increment'

这是我的递增操作

sale_products_controller.rb

  def increment
@pro = SaleProduct.find(params[:product_id])
@pro.increment!(:quantity)

@pro.save!
respond_to do |format|
  format.html { redirect_to sale_url(params[:id]), notice: 'Quantity was successfully increment.' }
  format.json { head :no_content }
end
end

这对我有用,但每次用户想要增加数量时都会加载页面

我怎么不能使用 ajax/javascript 来做呢

【问题讨论】:

    标签: javascript ruby-on-rails ajax ruby-on-rails-5


    【解决方案1】:

    link_to 使用remote: true 选项:

    <%= link_to ' + ', "/sale_products/#{params[:id]}/increment/#{s.id};", class: "btn btn-md btn-primary", remote: true %>
    

    看看它是如何工作的:https://guides.rubyonrails.org/working_with_javascript_in_rails.html#built-in-helpers

    要使其按预期工作,application.js 文件应包含 Rails UJS 文件。如果您使用标准的rails new 命令从头开始构建您的应用程序,它应该已经存在。否则,您可以手动添加:

    //= require rails-ujs
    

    更新:

    如果您不仅想发送 AJAX 请求,还想从服务器接收响应并更新页面的某些部分,那么编写自定义 JS 处理程序是不可避免的。通过单击您的链接,该处理程序将发起请求,解析响应并更新页面上的数据。

    使用 JQuery 可以这样做,例如:

    1. 为你的链接添加一个特殊的类来捕捉点击:

      <%= link_to ' + ', '#', data: { url: "/sale_products/#{params[:id]}/increment/#{s.id}" }, class: "btn btn-md btn-primary incrementor" %></td>
      
    2. 确保您的控制器操作响应您希望在页面上显示的数据:

      format.json { render json: { quantity: @pro.quantity } }
      
    3. 最后,将那个 JS 代码 sn-p 添加到你的 JS 中:

      $(function() {
        $(document).on('click', '.incrementor', function(e) {
          e.preventDefault();
          var $this = $(this);
          var url = $this.data('url');
      
          $.ajax({
            url: url,
            type: 'GET',
            beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}
      
          }).done(function(data) {
            if (data.quantity) {
              $('.quantity-updated').html(data.quantity);
            }
          });
        });
      });
      

      此代码的作用:当单击类为 incrementor 的链接时,它会从 HTML 元素的 url 数据属性中获取 URL,向该 URL 发送 GET 请求,解析响应以及是否具有 quantity 键用新的数量替换带有quantity-updated 类的 HTML 元素的内容。 (quantity-updated 仅用于说明;当然您需要插入自己的方法来查找要更新的元素。)

    【讨论】:

    • 感谢您的回复,我必须添加 remote: true ?没有任何javascript代码!?
    • 正确,您的链接不需要额外的 JS 代码。但是您必须将 Rails UJS 文件包含在您的application.js 中。如果您使用标准 rails new 命令从头开始构建您的应用程序,它应该在那里。否则,您可以手动添加://= require rails-ujs
    • 谢谢,现在的问题是用户看不到新值,他应该重新加载页面!!!!!!
    • 为什么不创建一个新的控制器方法和一个js.erb 来渲染部分视图,以便在视图中进行更改以使其工作?
    【解决方案2】:

    另一种方法是进行远程调用

    <%= link_to ' + ', "/sale_products/#{params[:id]}/increment/#{s.id};", class: "btn btn-md btn-primary", remote: true %>

    然后在你的增量方法中的控制器中:

    def increment
      @pro = SaleProduct.find(params[:product_id])
      @pro.increment!(:quantity)
    end
    

    创建一个文件来处理jquery,它必须与方法同名。

    文件将是: increment.js.erb

    这个文件的内容:

    $('.quantity-updated').html('<%= @pro.quantity %>');
    

    你就完成了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-21
      • 1970-01-01
      相关资源
      最近更新 更多