Ajax 在 Rails 中使用 jquery-ujs 时没有发生回调

Ajax callback not happening while using jquery-ujs in Rails

我的控制器是文件里面shipments_controller.rb的扩展版,shipments_controller_decorator.rb.

Spree::Api::ShipmentsController.class_eval do
  before_filter :find_and_update_shipment, only: [:ship, :ready, :add, :remove, :deliver]

  def deliver
    @shipment.deliver!
    respond_with(@shipment, default_template: :show)
  end
end

我的路线是:

put '/api/shipments/:id/deliver', :to => 'spree/api/shipments#deliver', :constraints => {:format => /json/} ,:as => "shipment_deliver"

application.js 文件中,我有

//= require jquery
//= require jquery_ujs
//= require bootstrap
$(document).ready(function(){
  $('a.deliver.button.fa.fa-arrow-right').on('ajax:success', function(data, status, xhr) {
    console.log("Hey!! I am there....")
    location.reload();
  });
})

我有观点_shipment.html.erb:

<div id="<%= "shipment_#{shipment.id}" %>" data-hook="admin_shipment_form">
  <%= render :partial => "spree/admin/variants/split", :formats => :js %>
  <fieldset class="no-border-bottom">
    <legend align="center" class="stock-location" data-hook="stock-location">
      <span class="shipment-number"><%= shipment.number %></span>
      -
      <span class="shipment-state"><%= Spree.t("shipment_states.#{shipment.state}") %></span>
      <%= Spree.t(:package_from) %>
      <strong class="stock-location-name" data-hook="stock-location-name">'<%= shipment.stock_location.name %>'</strong>
      <% if shipment.ready? and can? :update, shipment %>
        -
        <%= link_to Spree.t(:ship), '#', :class => 'ship button fa fa-arrow-right', :data => {'shipment-number' => shipment.number} %>
      <% elsif shipment.shipped? and can? :update, shipment %>
        -
        <%= link_to Spree.t(:deliver), main_app.shipment_deliver_path(shipment), {method: :put, :remote => true, data: {'shipment-number' => shipment.number}, :class => 'deliver button fa fa-arrow-right'} %>
      <% end %>
    </legend>
  </fieldset>

现在,当单击 Deliver link 时,将执行正确的控制器操作,并且所有数据都会更新到。但唯一没有发生的事情 页面重新加载 。调试 console.log 也没有打印任何东西。

我也看了 jquery-ujs wiki link,运气不好!

知道如何解决吗?

如果以下 gist suggestions 中的 none 有效,我认为您必须将 json 响应发送回 ajax 以使其收到它理解的响应.像这样:

respond_with(@shipment, default_template: :show) do |format|
  format.html { render }
  format.json { render json: @shipment }
end

由于您使用的是 "remote: true" 而不是 jquery 本机 Ajax,请尝试以下解决方案:

当您使用 "remote: true" 执行对服务器的 ajax 调用时(当然 rails 上使用 ruby ),您在控制器中执行了某个操作。在您的情况下,此操作是 "deliver"。在该操作中,您应该使用 js 进行响应并将您想要的数据发送回客户端。例如:

respond_with(@shipment, default_template: :show) do |format|
 format.html 
 format.js 
end

之后,您应该创建(在受尊重的视图目录中)一个以动作命名的文件,但不是 html 或 haml,而是 js。因此,如果您的控制器名为“ShippmentsController”并且您的操作是“deliver”,那么您应该创建一个名为“”的文件app/views/shippments/deliver.js.erb”。在那里你可以写 jquery/javascript 应该在 Ajax 完成时执行。

我找到了一个 work around

当我将覆盖的文件放入 vendor/assets/javascripts/spree/backend/shipments.js.erb 时,它不起作用。

当我输入时它起作用了 app/assets/javascripts/spree/backend/shipments.js.erb

工作Jquery代码:

//handle deliver click
  $('[data-hook=admin_shipment_form] a.deliver').on('click', function () {
    var link = $(this);
    var shipment_number = link.data('shipment-number');
    var url = Spree.url(Spree.routes.shipments_api + '/' + shipment_number + '/deliver.json');
    $.ajax({
      type: 'PUT',
      url: url
    }).done(function () {
      window.location.reload();
    }).error(function (msg) {
      console.log(msg);
    });
  });

而相关的视图html内容是:

<div id="<%= "shipment_#{shipment.id}" %>" data-hook="admin_shipment_form">
  <%= render :partial => "spree/admin/variants/split", :formats => :js %>
  <fieldset class="no-border-bottom">
    <legend align="center" class="stock-location" data-hook="stock-location">
      <span class="shipment-number"><%= shipment.number %></span>
      -
      <span class="shipment-state"><%= Spree.t("shipment_states.#{shipment.state}") %></span>
      <%= Spree.t(:package_from) %>
      <strong class="stock-location-name" data-hook="stock-location-name">'<%= shipment.stock_location.name %>'</strong>
      <% if shipment.ready? and can? :update, shipment %>
        -
        <%= link_to Spree.t(:ship), '#', :class => 'ship button fa fa-arrow-right', :data => {'shipment-number' => shipment.number} %>
      <% elsif shipment.shipped? and can? :update, shipment %>
        -
        <%= link_to Spree.t(:deliver), '#', :class => 'deliver button fa fa-arrow-right', :data => {'shipment-number' => shipment.number} %>
      <% end %>
    </legend>
  </fieldset>